diff --git a/threads-bugs/Makefile b/threads-bugs/Makefile index a2b5a94..c5c94a6 100644 --- a/threads-bugs/Makefile +++ b/threads-bugs/Makefile @@ -10,7 +10,8 @@ endif SRCS := atomicity.c \ atomicity_fixed.c \ ordering.c \ - ordering_fixed.c + ordering_fixed.c \ + deadlock.c OBJS := ${SRCS:c=o} PROGS := ${SRCS:.c=} diff --git a/threads-bugs/README.md b/threads-bugs/README.md index 992c305..d425553 100644 --- a/threads-bugs/README.md +++ b/threads-bugs/README.md @@ -14,6 +14,11 @@ Type `make` to build all examples. - `ordering.c`: Shows the ordering problem from the book chapter - `ordering_fixed.c`: Shows how to fix the problem with a condition variable +## Deadlock + +- `deadlock.c`: Shows simple two-cycle deadlock +- `deadlock_run.sh`: Script to run the above program many times, until you hit a deadlock and are convinced deadlock can occur + diff --git a/threads-bugs/deadlock.c b/threads-bugs/deadlock.c new file mode 100644 index 0000000..66867da --- /dev/null +++ b/threads-bugs/deadlock.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +#include "common.h" +#include "common_threads.h" + +pthread_mutex_t L1 = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t L2 = PTHREAD_MUTEX_INITIALIZER; + +void *thread1(void *arg) { + printf("t1: begin\n"); + printf("t1: try to acquire L1...\n"); + Pthread_mutex_lock(&L1); + printf("t1: L1 acquired\n"); + printf("t1: try to acquire L2...\n"); + Pthread_mutex_lock(&L2); + printf("t1: L2 acquired\n"); + Pthread_mutex_unlock(&L1); + Pthread_mutex_unlock(&L2); + return NULL; +} + +void *thread2(void *arg) { + printf(" t2: begin\n"); + printf(" t2: try to acquire L2...\n"); + Pthread_mutex_lock(&L2); + printf(" t2: L2 acquired\n"); + printf(" t2: try to acquire L1...\n"); + Pthread_mutex_lock(&L1); + printf(" t2: L1 acquired\n"); + Pthread_mutex_unlock(&L1); + Pthread_mutex_unlock(&L2); + + return NULL; +} + +int main(int argc, char *argv[]) { + if (argc != 1) { + fprintf(stderr, "usage: main\n"); + exit(1); + } + pthread_t p1, p2; + printf("main: begin\n"); + Pthread_create(&p1, NULL, thread1, NULL); + Pthread_create(&p2, NULL, thread2, NULL); + // join waits for the threads to finish + Pthread_join(p1, NULL); + Pthread_join(p2, NULL); + printf("main: end\n"); + return 0; +} + diff --git a/threads-bugs/deadlock_run.sh b/threads-bugs/deadlock_run.sh new file mode 100755 index 0000000..583d364 --- /dev/null +++ b/threads-bugs/deadlock_run.sh @@ -0,0 +1,7 @@ +#! /bin/bash + +while true; do + ./deadlock +done + +