]> Zhao Yanbai Git Server - minix.git/commitdiff
libmthread: add mthread_event_fire_all
authorRaja Appuswamy <raja@minix3.org>
Thu, 1 Dec 2011 13:52:25 +0000 (14:52 +0100)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 1 Dec 2011 13:53:20 +0000 (14:53 +0100)
common/include/minix/mthread.h
lib/libmthread/event.c
test/test59.c

index 38f335868c394aa7c6cd5f58d8f569a3f74513b1..94c9f4f66ce37c21dda9f8edbc1bc92b1b60f817 100644 (file)
@@ -139,6 +139,7 @@ _PROTOTYPE( int mthread_event_destroy, (mthread_event_t *event)     );
 _PROTOTYPE( int mthread_event_init, (mthread_event_t *event)   );
 _PROTOTYPE( int mthread_event_wait, (mthread_event_t *event)   );
 _PROTOTYPE( int mthread_event_fire, (mthread_event_t *event)   );
+_PROTOTYPE( int mthread_event_fire_all, (mthread_event_t *event));
 
 /* rwlock.c */
 _PROTOTYPE( int mthread_rwlock_destroy, (mthread_rwlock_t *rwlock)     );
index 12918006a97e8279a7138a242acea312da1f1139..9f52ca5f201cfbeb8f0a04d1836b84e57ff14bfa 100644 (file)
@@ -97,3 +97,30 @@ mthread_event_t *event; /* The event to be fired */
 
   return mthread_mutex_unlock(&event->mutex);
 }
+
+
+/*===========================================================================*
+ *                             mthread_event_fire_all                       *
+ *===========================================================================*/
+PUBLIC int mthread_event_fire_all(event)
+mthread_event_t *event; /* The event to be fired */
+{
+/* Fire an event, waking up any thread blocked on it.
+*/
+  int r;
+
+  if (!event)
+       return EINVAL;
+
+  r = mthread_mutex_lock(&event->mutex);
+  if (r != 0)
+       return r;
+
+  r = mthread_cond_broadcast(&event->cond);
+  if (r != 0) {
+       mthread_mutex_unlock(&event->mutex);
+       return r;
+  }
+
+  return mthread_mutex_unlock(&event->mutex);
+}
index 927dd8d94d21e7574f494a49df49c2940118a707..e15c4b9584efb1c8153b09e7db355d30c9e07489 100644 (file)
@@ -947,16 +947,20 @@ PRIVATE void *event_a(void *arg)
 {
   VERIFY_EVENT(0, 0, 21, 1);
 
+  /* Wait for main thread to signal us */
   if (mthread_event_wait(&event) != 0) err(21, 2);
 
+  /* Mark state transition and wakeup thread b */
   event_a_step = 1;
-
   if (mthread_event_fire(&event) != 0) err(21, 3);
-
   mthread_yield();
-
   VERIFY_EVENT(1, 1, 21, 4);
 
+  /* Wait for main thread to signal again with fireall  */
+  if (mthread_event_wait(&event) != 0) err(21, 5);
+
+  /* Marks state transition and exit */
+  event_a_step = 2;
   return(NULL);
 }
 
@@ -967,12 +971,16 @@ PRIVATE void *event_b(void *arg)
 {
   VERIFY_EVENT(0, 0, 22, 1);
 
+  /* Wait for thread a to signal us */
   if (mthread_event_wait(&event) != 0) err(22, 2);
-
   VERIFY_EVENT(1, 0, 22, 3);
 
+  /* Mark state transition and wait again, this time for main thread */
   event_b_step = 1;
+  if (mthread_event_wait(&event) != 0) err(21, 5);
 
+  /* Marks state transition and exit */
+  event_b_step = 2;
   return(NULL);
 }
 
@@ -990,21 +998,29 @@ PRIVATE void test_event(void)
   if (mthread_event_wait(NULL) == 0) err(23, 2);
   if (mthread_event_fire(NULL) == 0) err(23, 3);
 
+  /* create threads */
   if (mthread_create(&t[0], NULL, event_a, NULL) != 0) err(23, 4);
   if (mthread_create(&t[1], NULL, event_b, NULL) != 0) err(23, 5);
 
+  /* wait for them to block on event */
   mthread_yield_all();
-
   VERIFY_EVENT(0, 0, 23, 6);
 
+  /* Fire event to wakeup thread a */
   if (mthread_event_fire(&event) != 0) err(23, 7);
+  mthread_yield_all();
+  VERIFY_EVENT(1, 1, 23, 6);
 
+  /* Fire all to wakeup both a and b */
+  if (mthread_event_fire_all(&event) != 0) err(23, 7);
   mthread_yield_all();
+  VERIFY_EVENT(2, 2, 23, 8);
 
+  /* We are done here */
   for (i = 0; i < 2; i++)
-       if (mthread_join(t[i], NULL) != 0) err(23, 8);
+       if (mthread_join(t[i], NULL) != 0) err(23, 9);
 
-  if (mthread_event_destroy(&event) != 0) err(23, 9);
+  if (mthread_event_destroy(&event) != 0) err(23, 10);
 }
 
 /*===========================================================================*