From 89354869b0f754a8b9a867e7003d321070ab3886 Mon Sep 17 00:00:00 2001 From: Remzi Arpaci-Dusseau Date: Sun, 19 May 2019 12:14:44 -0500 Subject: [PATCH] ordering example: fixed --- threads-bugs/Makefile | 3 +- threads-bugs/README.md | 7 ++++ threads-bugs/ordering_fixed.c | 66 +++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 threads-bugs/ordering_fixed.c diff --git a/threads-bugs/Makefile b/threads-bugs/Makefile index de32462..a2b5a94 100644 --- a/threads-bugs/Makefile +++ b/threads-bugs/Makefile @@ -9,7 +9,8 @@ endif SRCS := atomicity.c \ atomicity_fixed.c \ - ordering.c + ordering.c \ + ordering_fixed.c OBJS := ${SRCS:c=o} PROGS := ${SRCS:.c=} diff --git a/threads-bugs/README.md b/threads-bugs/README.md index bf932b0..992c305 100644 --- a/threads-bugs/README.md +++ b/threads-bugs/README.md @@ -7,6 +7,13 @@ Type `make` to build all examples. ## Atomicity Failure - `atomicity.c`: Shows how uncareful check-then-use can crash code +- `atomicity_fixed.c`: Shows how to fix the problem with a lock + +## Ordering Violation + +- `ordering.c`: Shows the ordering problem from the book chapter +- `ordering_fixed.c`: Shows how to fix the problem with a condition variable + diff --git a/threads-bugs/ordering_fixed.c b/threads-bugs/ordering_fixed.c new file mode 100644 index 0000000..3f21411 --- /dev/null +++ b/threads-bugs/ordering_fixed.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +#include "common.h" +#include "common_threads.h" + +#define PR_STATE_INIT (0) + +typedef struct { + pthread_t Tid; + int State; +} pr_thread_t; + +pr_thread_t *PR_CreateThread(void *(*start_routine)(void *)) { + pr_thread_t *p = malloc(sizeof(pr_thread_t)); + if (p == NULL) + return NULL; + p->State = PR_STATE_INIT; + Pthread_create(&p->Tid, NULL, start_routine, NULL); + // turn the sleep off to avoid the fault, sometimes... + sleep(1); + return p; +} + +void PR_WaitThread(pr_thread_t *p) { + Pthread_join(p->Tid, NULL); +} + +pr_thread_t *mThread; + +pthread_mutex_t mtLock = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t mtCond = PTHREAD_COND_INITIALIZER; +int mtInit = 0; + +void *mMain(void *arg) { + printf("mMain: begin\n"); + + // wait for thread structure to be initialized + Pthread_mutex_lock(&mtLock); + while (mtInit == 0) + Pthread_cond_wait(&mtCond, &mtLock); + Pthread_mutex_unlock(&mtLock); + + int mState = mThread->State; + printf("mMain: state is %d\n", mState); + return NULL; +} + + +int main(int argc, char *argv[]) { + printf("ordering: begin\n"); + mThread = PR_CreateThread(mMain); + + // signal: thread has been created, and mThread initialized + Pthread_mutex_lock(&mtLock); + mtInit = 1; + Pthread_cond_signal(&mtCond); + Pthread_mutex_unlock(&mtLock); + + PR_WaitThread(mThread); + printf("ordering: end\n"); + return 0; +} +