From a2d7e3595dbcb4d3a9e9d046f5acd49d4e8bc87e Mon Sep 17 00:00:00 2001 From: Remzi Arpaci-Dusseau Date: Mon, 29 Apr 2019 14:39:06 -0500 Subject: [PATCH] first bits of CV code --- threads-cv/Makefile | 20 +++++++++++++ threads-cv/join.c | 31 ++++++++++++++++++++ threads-cv/join_modular.c | 60 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 threads-cv/Makefile create mode 100644 threads-cv/join.c create mode 100644 threads-cv/join_modular.c diff --git a/threads-cv/Makefile b/threads-cv/Makefile new file mode 100644 index 0000000..0124b54 --- /dev/null +++ b/threads-cv/Makefile @@ -0,0 +1,20 @@ +CC := gcc +CFLAGS := -Wall -Werror -I../include + +SRCS := join.c \ + join_modular.c + +OBJS := ${SRCS:c=o} +PROGS := ${SRCS:.c=} + +.PHONY: all +all: ${PROGS} + +${PROGS} : % : %.o Makefile + ${CC} $< -o $@ -pthread + +clean: + rm -f ${PROGS} ${OBJS} + +%.o: %.c Makefile + ${CC} ${CFLAGS} -c $< diff --git a/threads-cv/join.c b/threads-cv/join.c new file mode 100644 index 0000000..af1d883 --- /dev/null +++ b/threads-cv/join.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include "common.h" +#include "common_threads.h" + +pthread_cond_t c = PTHREAD_COND_INITIALIZER; +pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; +int done = 0; + +void *child(void *arg) { + printf("child\n"); + sleep(1); + Mutex_lock(&m); + done = 1; + Cond_signal(&c); + Mutex_unlock(&m); + return NULL; +} +int main(int argc, char *argv[]) { + pthread_t p; + printf("parent: begin\n"); + Pthread_create(&p, NULL, child, NULL); + Mutex_lock(&m); + while (done == 0) + Cond_wait(&c, &m); // releases lock when going to sleep + Mutex_unlock(&m); + printf("parent: end\n"); + return 0; +} + diff --git a/threads-cv/join_modular.c b/threads-cv/join_modular.c new file mode 100644 index 0000000..5cfc101 --- /dev/null +++ b/threads-cv/join_modular.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include "common.h" +#include "common_threads.h" + +// +// Simple sync "object" +// + +typedef struct { + pthread_cond_t c; + pthread_mutex_t m; + int done; +} synchronizer_t; + +synchronizer_t s; + +void sync_init(synchronizer_t *s) { + s->done = 0; + Mutex_init(&s->m); + Cond_init(&s->c); +} + +void sync_signal(synchronizer_t *s) { + Mutex_lock(&s->m); + s->done = 1; + Cond_signal(&s->c); + Mutex_unlock(&s->m); +} + +void sync_wait(synchronizer_t *s) { + Mutex_lock(&s->m); + while (s->done == 0) + Cond_wait(&s->c, &s->m); + s->done = 0; // reset for next use + Mutex_unlock(&s->m); +} + + +// +// Main threads +// + +void *child(void *arg) { + printf("child\n"); + sleep(1); + sync_signal(&s); + return NULL; +} +int main(int argc, char *argv[]) { + pthread_t p; + printf("parent: begin\n"); + sync_init(&s); + Pthread_create(&p, NULL, child, NULL); + sync_wait(&s); + printf("parent: end\n"); + return 0; +} +