Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Change the prototype of xbt_thread_create(), sorry.
[simgrid.git] / examples / gras / synchro / philosopher.c
index 8624696..9bda397 100644 (file)
@@ -10,7 +10,7 @@
 #include "gras.h"
 #include "xbt/synchro.h"
 
-XBT_LOG_NEW_DEFAULT_CATEGORY(philo,"Logs of this example");
+XBT_LOG_NEW_DEFAULT_CATEGORY(philo, "Logs of this example");
 
 
 /** Philosopher logic **/
@@ -24,34 +24,39 @@ xbt_cond_t *forks;
 #define EATING 1
 int *state;
 
-int *id; /* to pass a pointer to the threads without race condition */
-
-static void pickup(int id, int lunch)  {
-   INFO2("Thread %d gets hungry (lunch #%d)",id,lunch);
-   xbt_mutex_lock(mutex);
-   while (state[(id + (philosopher_amount-1))%philosopher_amount] == EATING ||
-         state[(id + 1)%philosopher_amount] == EATING) 
-     {
-       xbt_cond_wait(forks[id], mutex);
-     }
-   
-   state[id] = EATING;
-   xbt_assert1(state[(id + (philosopher_amount-1))%philosopher_amount] == THINKING &&
-              state[(id + 1)%philosopher_amount] == THINKING ,
-              "Philosopher %d eats at the same time that one of its neighbors!!!",id);
-       
-   xbt_mutex_unlock(mutex);
-   INFO1("Thread %d eats",id);
+int *id;                        /* to pass a pointer to the threads without race condition */
+
+static void pickup(int id, int lunch)
+{
+  INFO2("Thread %d gets hungry (lunch #%d)", id, lunch);
+  xbt_mutex_acquire(mutex);
+  while (state[(id + (philosopher_amount - 1)) % philosopher_amount] == EATING
+         || state[(id + 1) % philosopher_amount] == EATING) {
+    xbt_cond_wait(forks[id], mutex);
+  }
+
+  state[id] = EATING;
+  xbt_assert1(state[(id + (philosopher_amount - 1)) % philosopher_amount] ==
+              THINKING
+              && state[(id + 1) % philosopher_amount] == THINKING,
+              "Philosopher %d eats at the same time that one of its neighbors!!!",
+              id);
+
+  xbt_mutex_release(mutex);
+  INFO1("Thread %d eats", id);
 }
-static void putdown(int id)  {
-   INFO1("Thread %d is full",id);
-   xbt_mutex_lock(mutex);
-   state[id] = THINKING;
-   xbt_cond_signal(forks[(id+(philosopher_amount-1))%philosopher_amount]);
-   xbt_cond_signal(forks[(id+1)%philosopher_amount]);
-   
-   xbt_mutex_unlock(mutex);
-   INFO1("Thread %d thinks",id);
+
+static void putdown(int id)
+{
+  INFO1("Thread %d is full", id);
+  xbt_mutex_acquire(mutex);
+  state[id] = THINKING;
+  xbt_cond_signal(forks
+                  [(id + (philosopher_amount - 1)) % philosopher_amount]);
+  xbt_cond_signal(forks[(id + 1) % philosopher_amount]);
+
+  xbt_mutex_release(mutex);
+  INFO1("Thread %d thinks", id);
 }
 
 /*
@@ -64,79 +69,84 @@ int running_threads;
 xbt_mutex_t dead_end;
 
 /* Code ran by each thread */
-static void philo_thread(void *arg) {
-   int id = *(int*)arg;
-   int i;
-   
-   for (i=0; i<lunch_amount; i++) {
-      pickup(id,i);
-      gras_os_sleep(id / 100.0); /* each philosopher sleeps and eat a time related to its ID */
-      putdown(id);
-      gras_os_sleep(id / 100.0);
-   }
-   
-   xbt_mutex_lock(mut_end);
-   running_threads--;
-   xbt_cond_signal(cond_end);
-   xbt_mutex_unlock(mut_end);
-
-   /* Enter an endless loop to test the killing facilities */
-   INFO1("Thread %d tries to enter the dead-end; hopefully, the master will cancel it",id);
-   xbt_mutex_lock(dead_end);
-   INFO1("Oops, thread %d reached the dead-end. Cancelation failed",id);
+static void philo_thread(void *arg)
+{
+  int id = *(int *) arg;
+  int i;
+
+  for (i = 0; i < lunch_amount; i++) {
+    pickup(id, i);
+    gras_os_sleep(id / 100.0);  /* each philosopher sleeps and eat a time related to its ID */
+    putdown(id);
+    gras_os_sleep(id / 100.0);
+  }
+
+  xbt_mutex_acquire(mut_end);
+  running_threads--;
+  xbt_cond_signal(cond_end);
+  xbt_mutex_release(mut_end);
+
+  /* Enter an endless loop to test the killing facilities */
+  INFO1
+    ("Thread %d tries to enter the dead-end; hopefully, the master will cancel it",
+     id);
+  xbt_mutex_acquire(dead_end);
+  INFO1("Oops, thread %d reached the dead-end. Cancelation failed", id);
 }
 
-int philosopher (int argc,char *argv[]);
-int philosopher (int argc,char *argv[]) {
+int philosopher(int argc, char *argv[]);
+int philosopher(int argc, char *argv[])
+{
   int i;
   xbt_thread_t *philosophers;
-   
-  gras_init(&argc,argv);
-  xbt_assert0(argc>=2,"This program expects one argument (the amount of philosophers)");
 
-  INFO0("Wait 1 sec to check that gras_os_sleep do works");
-  gras_os_sleep(1);
-   
+  gras_init(&argc, argv);
+  xbt_assert0(argc >= 2,
+              "This program expects one argument (the amount of philosophers)");
+
   /* initializations of the philosopher mecanisms */
   philosopher_amount = atoi(argv[1]);
-  state = xbt_new0(int,philosopher_amount); 
-  id = xbt_new0(int,philosopher_amount); 
-  forks = xbt_new(xbt_cond_t,philosopher_amount);
-  philosophers = xbt_new(xbt_thread_t,philosopher_amount);
-     
+  state = xbt_new0(int, philosopher_amount);
+  id = xbt_new0(int, philosopher_amount);
+  forks = xbt_new(xbt_cond_t, philosopher_amount);
+  philosophers = xbt_new(xbt_thread_t, philosopher_amount);
+
   mutex = xbt_mutex_init();
-  for (i=0; i<philosopher_amount; i++) {
-     state[i] = THINKING;
-     id[i] = i;
-     forks[i] = xbt_cond_init();
+  for (i = 0; i < philosopher_amount; i++) {
+    state[i] = THINKING;
+    id[i] = i;
+    forks[i] = xbt_cond_init();
   }
-   
+
   /* setup the ending mecanism */
-  running_threads = philosopher_amount; 
+  running_threads = philosopher_amount;
   cond_end = xbt_cond_init();
   mut_end = xbt_mutex_init();
   dead_end = xbt_mutex_init();
-  xbt_mutex_lock(dead_end);
-  
-  INFO0("Enough waiting, spawn the threads");
+  xbt_mutex_acquire(dead_end);
+
+  INFO2("Spawn the %d threads (%d lunches scheduled)", philosopher_amount,
+        lunch_amount);
   /* spawn threads */
-  for (i=0; i<philosopher_amount; i++)
-     philosophers[i] = xbt_thread_create(philo_thread,&id[i]);
-  
+  for (i = 0; i < philosopher_amount; i++) {
+    char *name = bprintf("thread %d", i);
+    philosophers[i] = xbt_thread_create(name, philo_thread, &id[i],0/*not joinable*/);
+    free(name);
+  }
+
   /* wait for them */
-  xbt_mutex_lock(mut_end);
-  while (running_threads) 
-     xbt_cond_wait(cond_end,mut_end);
-  xbt_mutex_unlock(mut_end);
-       
+  xbt_mutex_acquire(mut_end);
+  while (running_threads)
+    xbt_cond_wait(cond_end, mut_end);
+  xbt_mutex_release(mut_end);
+
   INFO0("Cancel all childs");
   /* nuke them threads */
-  for (i=0; i<philosopher_amount; i++) {
-    INFO1("Canceling %p",philosophers[i]);
-     xbt_thread_cancel(philosophers[i]);
+  for (i = 0; i < philosopher_amount; i++) {
+    xbt_thread_cancel(philosophers[i]);
   }
 
-  xbt_mutex_unlock(dead_end);
+  xbt_mutex_release(dead_end);
   gras_exit();
   return 0;
 }