From bb639b166c10368810cbec7477696c1780a276f9 Mon Sep 17 00:00:00 2001 From: Remzi Arpaci-Dusseau Date: Wed, 8 May 2019 14:35:39 -0500 Subject: [PATCH] solution for atomicity bug --- threads-bugs/Makefile | 3 +- threads-bugs/atomicity_fixed.c | 66 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 threads-bugs/atomicity_fixed.c diff --git a/threads-bugs/Makefile b/threads-bugs/Makefile index fff9c59..3e04898 100644 --- a/threads-bugs/Makefile +++ b/threads-bugs/Makefile @@ -7,7 +7,8 @@ ifeq ($(OS),Linux) LIBS += -pthread endif -SRCS := atomicity.c +SRCS := atomicity.c \ + atomicity_fixed.c OBJS := ${SRCS:c=o} PROGS := ${SRCS:.c=} diff --git a/threads-bugs/atomicity_fixed.c b/threads-bugs/atomicity_fixed.c new file mode 100644 index 0000000..cb71dc9 --- /dev/null +++ b/threads-bugs/atomicity_fixed.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +#include "common.h" +#include "common_threads.h" + +pthread_mutex_t proc_info_lock = PTHREAD_MUTEX_INITIALIZER; + +typedef struct { + int pid; +} proc_t; + +typedef struct { + proc_t *proc_info; +} thread_info_t; + +proc_t p; +thread_info_t th; +thread_info_t *thd; + +void *thread1(void *arg) { + printf("t1: before check\n"); + Pthread_mutex_lock(&proc_info_lock); + if (thd->proc_info) { + printf("t1: after check\n"); + sleep(2); + printf("t1: use!\n"); + printf("%d\n", thd->proc_info->pid); + } + Pthread_mutex_unlock(&proc_info_lock); + return NULL; +} + +void *thread2(void *arg) { + printf(" t2: begin\n"); + sleep(1); // change to 5 to make the code "work"... + Pthread_mutex_lock(&proc_info_lock); + printf(" t2: set to NULL\n"); + thd->proc_info = NULL; + Pthread_mutex_unlock(&proc_info_lock); + return NULL; +} + +int main(int argc, char *argv[]) { + if (argc != 1) { + fprintf(stderr, "usage: main\n"); + exit(1); + } + thread_info_t t; + p.pid = 100; + t.proc_info = &p; + thd = &t; + + pthread_t p1, p2; + printf("main: begin\n"); + Pthread_create(&p1, NULL, thread1, NULL); + Pthread_create(&p2, NULL, thread2, NULL); + // join waits for the threads to finish + Pthread_join(p1, NULL); + Pthread_join(p2, NULL); + printf("main: end\n"); + return 0; +} +