diff --git a/threads-sema/Makefile b/threads-sema/Makefile index 927d969..8ab4f2b 100644 --- a/threads-sema/Makefile +++ b/threads-sema/Makefile @@ -1,7 +1,12 @@ CC := gcc CFLAGS := -Wall -Werror -I../include -SRCS := dining_philosophers_deadlock.c dining_philosophers_deadlock_print.c dining_philosophers_no_deadlock.c dining_philosophers_no_deadlock_print.c join.c +SRCS := dining_philosophers_deadlock.c \ + dining_philosophers_deadlock_print.c \ + dining_philosophers_no_deadlock.c \ + dining_philosophers_no_deadlock_print.c \ + join.c \ + zemaphore.c OBJS := ${SRCS:c=o} PROGS := ${SRCS:.c=} diff --git a/threads-sema/zemaphore.c b/threads-sema/zemaphore.c new file mode 100644 index 0000000..74979e6 --- /dev/null +++ b/threads-sema/zemaphore.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +#include "common.h" +#include "common_threads.h" + +typedef struct __Zem_t { + int value; + pthread_cond_t cond; + pthread_mutex_t lock; +} Zem_t; + +void Zem_init(Zem_t *z, int value) { + z->value = value; + Cond_init(&z->cond); + Mutex_init(&z->lock); +} + +void Zem_wait(Zem_t *z) { + Mutex_lock(&z->lock); + while (z->value <= 0) + Cond_wait(&z->cond, &z->lock); + z->value--; + Mutex_unlock(&z->lock); +} + +void Zem_post(Zem_t *z) { + Mutex_lock(&z->lock); + z->value++; + Cond_signal(&z->cond); + Mutex_unlock(&z->lock); +} + + +Zem_t s; + +void *child(void *arg) { + sleep(4); + printf("child\n"); + Zem_post(&s); // signal here: child is done + return NULL; +} + +int main(int argc, char *argv[]) { + Zem_init(&s, 0); + printf("parent: begin\n"); + pthread_t c; + Pthread_create(&c, NULL, child, NULL); + Zem_wait(&s); // wait here for child + printf("parent: end\n"); + return 0; +} +