From 3faa28e520a3b4d95ea1d190c7830cd33bb841f0 Mon Sep 17 00:00:00 2001 From: Remzi Arpaci-Dusseau Date: Thu, 16 May 2019 16:07:33 -0500 Subject: [PATCH] made it so that zemaphore is used on mac, semaphore on linux, and other clean up --- threads-sema/Makefile | 13 +++-- threads-sema/binary.c | 8 +++- threads-sema/dining_philosophers_deadlock.c | 6 +++ .../dining_philosophers_deadlock_print.c | 6 +++ .../dining_philosophers_no_deadlock.c | 6 +++ .../dining_philosophers_no_deadlock_print.c | 6 +++ threads-sema/join.c | 8 +++- threads-sema/producer_consumer_works.c | 7 ++- threads-sema/rwlock.c | 7 ++- threads-sema/throttle.c | 48 +++++++++++++++++++ threads-sema/zemaphore.c | 29 +---------- threads-sema/zemaphore.h | 37 ++++++++++++++ 12 files changed, 146 insertions(+), 35 deletions(-) create mode 100644 threads-sema/throttle.c create mode 100644 threads-sema/zemaphore.h diff --git a/threads-sema/Makefile b/threads-sema/Makefile index 0d7aba7..9c00298 100644 --- a/threads-sema/Makefile +++ b/threads-sema/Makefile @@ -1,5 +1,11 @@ CC := gcc -CFLAGS := -Wall -Werror -I../include +CFLAGS := -Wall -Werror -I../include -pthread + +OS := $(shell uname -s) +LIBS := +ifeq ($(OS),Linux) + LIBS += -pthread +endif SRCS := dining_philosophers_deadlock.c \ dining_philosophers_deadlock_print.c \ @@ -9,7 +15,8 @@ SRCS := dining_philosophers_deadlock.c \ binary.c \ producer_consumer_works.c \ rwlock.c \ - zemaphore.c + zemaphore.c \ + throttle.c OBJS := ${SRCS:c=o} PROGS := ${SRCS:.c=} @@ -18,7 +25,7 @@ PROGS := ${SRCS:.c=} all: ${PROGS} ${PROGS} : % : %.o Makefile - ${CC} $< -o $@ -pthread + ${CC} $< -o $@ ${LIBS} clean: rm -f ${PROGS} ${OBJS} diff --git a/threads-sema/binary.c b/threads-sema/binary.c index 93df440..31918f6 100644 --- a/threads-sema/binary.c +++ b/threads-sema/binary.c @@ -6,6 +6,12 @@ #include "common.h" #include "common_threads.h" +#ifdef linux +#include +#elif __APPLE__ +#include "zemaphore.h" +#endif + sem_t mutex; volatile int counter = 0; @@ -26,7 +32,7 @@ int main(int argc, char *argv[]) { Pthread_create(&c2, NULL, child, NULL); Pthread_join(c1, NULL); Pthread_join(c2, NULL); - printf("result: %d\n", counter); + printf("result: %d (should be 20000000)\n", counter); return 0; } diff --git a/threads-sema/dining_philosophers_deadlock.c b/threads-sema/dining_philosophers_deadlock.c index 84db8d6..9b06e78 100644 --- a/threads-sema/dining_philosophers_deadlock.c +++ b/threads-sema/dining_philosophers_deadlock.c @@ -5,6 +5,12 @@ #include "common.h" #include "common_threads.h" +#ifdef linux +#include +#elif __APPLE__ +#include "zemaphore.h" +#endif + typedef struct { int num_loops; int thread_id; diff --git a/threads-sema/dining_philosophers_deadlock_print.c b/threads-sema/dining_philosophers_deadlock_print.c index 4951dd6..5b51c78 100644 --- a/threads-sema/dining_philosophers_deadlock_print.c +++ b/threads-sema/dining_philosophers_deadlock_print.c @@ -5,6 +5,12 @@ #include "common.h" #include "common_threads.h" +#ifdef linux +#include +#elif __APPLE__ +#include "zemaphore.h" +#endif + typedef struct { int num_loops; int thread_id; diff --git a/threads-sema/dining_philosophers_no_deadlock.c b/threads-sema/dining_philosophers_no_deadlock.c index 6840410..498226b 100644 --- a/threads-sema/dining_philosophers_no_deadlock.c +++ b/threads-sema/dining_philosophers_no_deadlock.c @@ -5,6 +5,12 @@ #include "common.h" #include "common_threads.h" +#ifdef linux +#include +#elif __APPLE__ +#include "zemaphore.h" +#endif + typedef struct { int num_loops; int thread_id; diff --git a/threads-sema/dining_philosophers_no_deadlock_print.c b/threads-sema/dining_philosophers_no_deadlock_print.c index 84afce8..7fc3e37 100644 --- a/threads-sema/dining_philosophers_no_deadlock_print.c +++ b/threads-sema/dining_philosophers_no_deadlock_print.c @@ -5,6 +5,12 @@ #include "common.h" #include "common_threads.h" +#ifdef linux +#include +#elif __APPLE__ +#include "zemaphore.h" +#endif + typedef struct { int num_loops; int thread_id; diff --git a/threads-sema/join.c b/threads-sema/join.c index e9de1ff..7d094b0 100644 --- a/threads-sema/join.c +++ b/threads-sema/join.c @@ -6,10 +6,16 @@ #include "common.h" #include "common_threads.h" +#ifdef linux +#include +#elif __APPLE__ +#include "zemaphore.h" +#endif + sem_t s; void *child(void *arg) { - sleep(4); + sleep(2); printf("child\n"); Sem_post(&s); // signal here: child is done return NULL; diff --git a/threads-sema/producer_consumer_works.c b/threads-sema/producer_consumer_works.c index 798ade0..df5d201 100644 --- a/threads-sema/producer_consumer_works.c +++ b/threads-sema/producer_consumer_works.c @@ -3,11 +3,16 @@ #include #include #include -#include #include "common.h" #include "common_threads.h" +#ifdef linux +#include +#elif __APPLE__ +#include "zemaphore.h" +#endif + int max; int loops; int *buffer; diff --git a/threads-sema/rwlock.c b/threads-sema/rwlock.c index 6b2bc10..766729d 100644 --- a/threads-sema/rwlock.c +++ b/threads-sema/rwlock.c @@ -1,12 +1,17 @@ #include #include #include -#include #include #include "common.h" #include "common_threads.h" +#ifdef linux +#include +#elif __APPLE__ +#include "zemaphore.h" +#endif + typedef struct _rwlock_t { sem_t writelock; sem_t lock; diff --git a/threads-sema/throttle.c b/threads-sema/throttle.c new file mode 100644 index 0000000..3a6b436 --- /dev/null +++ b/threads-sema/throttle.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +#include "common.h" +#include "common_threads.h" + +#ifdef linux +#include +#elif __APPLE__ +#include "zemaphore.h" +#endif + +sem_t s; + +void *child(void *arg) { + Sem_wait(&s); + printf("child %lld\n", (long long int) arg); + sleep(1); + Sem_post(&s); + return NULL; +} + +int main(int argc, char *argv[]) { + if (argc != 3) { + fprintf(stderr, "usage: throttle \n"); + exit(1); + } + int num_threads = atoi(argv[1]); + int sem_value = atoi(argv[2]); + + Sem_init(&s, sem_value); + + printf("parent: begin\n"); + pthread_t c[num_threads]; + + int i; + for (i = 0; i < num_threads; i++) + Pthread_create(&c[i], NULL, child, (void *) (long long int)i); + + for (i = 0; i < num_threads; i++) + Pthread_join(c[i], NULL); + + printf("parent: end\n"); + return 0; +} + diff --git a/threads-sema/zemaphore.c b/threads-sema/zemaphore.c index 74979e6..5a2c85e 100644 --- a/threads-sema/zemaphore.c +++ b/threads-sema/zemaphore.c @@ -5,34 +5,7 @@ #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); -} - +#include "zemaphore.h" Zem_t s; diff --git a/threads-sema/zemaphore.h b/threads-sema/zemaphore.h new file mode 100644 index 0000000..3b6639a --- /dev/null +++ b/threads-sema/zemaphore.h @@ -0,0 +1,37 @@ +#ifndef __zemaphore_h__ +#define __zemaphore_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); +} + +typedef Zem_t sem_t; + +#define Sem_wait(s) Zem_wait(s) +#define Sem_post(s) Zem_post(s) +#define Sem_init(s, v) Zem_init(s, v) + +#endif // __zemaphore_h__