From f9d1614e6d4ea3d48efe343c474a47304283a842 Mon Sep 17 00:00:00 2001 From: Raja Appuswamy Date: Thu, 1 Dec 2011 14:52:25 +0100 Subject: [PATCH] libmthread: add mthread_event_fire_all --- common/include/minix/mthread.h | 1 + lib/libmthread/event.c | 27 +++++++++++++++++++++++++++ test/test59.c | 30 +++++++++++++++++++++++------- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/common/include/minix/mthread.h b/common/include/minix/mthread.h index 38f335868..94c9f4f66 100644 --- a/common/include/minix/mthread.h +++ b/common/include/minix/mthread.h @@ -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) ); diff --git a/lib/libmthread/event.c b/lib/libmthread/event.c index 12918006a..9f52ca5f2 100644 --- a/lib/libmthread/event.c +++ b/lib/libmthread/event.c @@ -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); +} diff --git a/test/test59.c b/test/test59.c index 927dd8d94..e15c4b958 100644 --- a/test/test59.c +++ b/test/test59.c @@ -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); } /*===========================================================================* -- 2.44.0