Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add more tests from McMini
[simgrid.git] / teshsuite / mc / mcmini / philosophers_mutex_deadlock.c
diff --git a/teshsuite/mc/mcmini/philosophers_mutex_deadlock.c b/teshsuite/mc/mcmini/philosophers_mutex_deadlock.c
new file mode 100644 (file)
index 0000000..4497df7
--- /dev/null
@@ -0,0 +1,59 @@
+// Naive dining philosophers solution, which leads to deadlock.
+
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+int DEBUG = 0;
+
+struct forks {
+    int philosopher;
+    pthread_mutex_t *left_fork;
+    pthread_mutex_t *right_fork;
+} *forks;
+
+static void * philosopher_doit(void *forks_arg) {
+    struct forks *forks = forks_arg;
+    pthread_mutex_lock(forks->left_fork);
+    pthread_mutex_lock(forks->right_fork);
+
+    if(DEBUG) printf("Philosopher %d just ate.\n", forks->philosopher);
+    
+    pthread_mutex_unlock(forks->left_fork);
+    pthread_mutex_unlock(forks->right_fork);
+    return NULL;
+}
+
+int main(int argc, char* argv[]) {
+    if(argc != 3){
+        printf("Usage: %s NUM_PHILOSOPHERS DEBUG\n", argv[0]);
+        return 1;
+    }
+
+    int NUM_THREADS = atoi(argv[1]);
+    DEBUG = atoi(argv[2]);
+
+    pthread_t thread[NUM_THREADS];
+    pthread_mutex_t mutex_resource[NUM_THREADS];
+
+    forks = malloc(NUM_THREADS * sizeof(struct forks));
+
+    int i;
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_mutex_init(&mutex_resource[i], NULL);
+        forks[i] = (struct forks){i,
+                                  &mutex_resource[i], &mutex_resource[(i+1) % NUM_THREADS]};
+    }
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_create(&thread[i], NULL, &philosopher_doit, &forks[i]);
+    }
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        pthread_join(thread[i], NULL);
+    }
+
+    free(forks);
+    return 0;
+}