diff --git a/lab5/demos/pthread_count_2_mutex.c b/lab5/demos/pthread_count_2_mutex.c new file mode 100644 index 0000000..4423722 --- /dev/null +++ b/lab5/demos/pthread_count_2_mutex.c @@ -0,0 +1,68 @@ +/* + * This program ends up in a threadrace when the argument is around 1M + * + * We need synchronization primitives to help here! + */ +#include +#include +#include + +struct args { + int max; + char letter; + pthread_mutex_t* mutex; +}; + +volatile int counter = 0; + +void* count_thread(void* arg) { + struct args* a = arg; + + for (int i = 0; i < a->max; i++) { + pthread_mutex_lock(a->mutex); + counter = counter + 1; + pthread_mutex_unlock(a->mutex); + } + + // // But given this process is pretty fast... this is better + // pthread_mutex_lock(a->mutex); + // for (int i = 0; i < a->max; i++) { + // counter = counter + 1; + // } + // pthread_mutex_unlock(a->mutex); + + printf("Thread %c: done with counter at %d\n", a->letter, counter); + return NULL; +} + +void* make_args(int max, char letter, pthread_mutex_t* mutex) { + struct args* a = malloc(sizeof(struct args)); + a->max = max; + a->letter = letter; + a->mutex = mutex; + + return (void*) a; +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + exit(1); + } + + int max = atoi(argv[1]); + + pthread_mutex_t* mutex = malloc(sizeof(pthread_mutex_t)); + pthread_mutex_init(mutex, NULL); + + pthread_t p1, p2; + pthread_create(&p1, NULL, count_thread, make_args(max, 'A', mutex)); + pthread_create(&p2, NULL, count_thread, make_args(max, 'B', mutex)); + + pthread_join(p1, NULL); + pthread_join(p2, NULL); + + pthread_mutex_destroy(mutex); + + printf("main: done\n [counter: %d]\n [should: %d]\n", counter, max * 2); + return 0; +}