libmthread: add mthread_event_fire_all

This commit is contained in:
Raja Appuswamy 2011-12-01 14:52:25 +01:00 committed by David van Moolenbroek
parent 8a0b9de41a
commit f9d1614e6d
3 changed files with 52 additions and 8 deletions

View 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_init, (mthread_event_t *event) );
_PROTOTYPE( int mthread_event_wait, (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, (mthread_event_t *event) );
_PROTOTYPE( int mthread_event_fire_all, (mthread_event_t *event));
/* rwlock.c */ /* rwlock.c */
_PROTOTYPE( int mthread_rwlock_destroy, (mthread_rwlock_t *rwlock) ); _PROTOTYPE( int mthread_rwlock_destroy, (mthread_rwlock_t *rwlock) );

View file

@ -97,3 +97,30 @@ mthread_event_t *event; /* The event to be fired */
return mthread_mutex_unlock(&event->mutex); 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);
}

View file

@ -947,16 +947,20 @@ PRIVATE void *event_a(void *arg)
{ {
VERIFY_EVENT(0, 0, 21, 1); VERIFY_EVENT(0, 0, 21, 1);
/* Wait for main thread to signal us */
if (mthread_event_wait(&event) != 0) err(21, 2); if (mthread_event_wait(&event) != 0) err(21, 2);
/* Mark state transition and wakeup thread b */
event_a_step = 1; event_a_step = 1;
if (mthread_event_fire(&event) != 0) err(21, 3); if (mthread_event_fire(&event) != 0) err(21, 3);
mthread_yield(); mthread_yield();
VERIFY_EVENT(1, 1, 21, 4); 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); return(NULL);
} }
@ -967,12 +971,16 @@ PRIVATE void *event_b(void *arg)
{ {
VERIFY_EVENT(0, 0, 22, 1); VERIFY_EVENT(0, 0, 22, 1);
/* Wait for thread a to signal us */
if (mthread_event_wait(&event) != 0) err(22, 2); if (mthread_event_wait(&event) != 0) err(22, 2);
VERIFY_EVENT(1, 0, 22, 3); VERIFY_EVENT(1, 0, 22, 3);
/* Mark state transition and wait again, this time for main thread */
event_b_step = 1; event_b_step = 1;
if (mthread_event_wait(&event) != 0) err(21, 5);
/* Marks state transition and exit */
event_b_step = 2;
return(NULL); return(NULL);
} }
@ -990,21 +998,29 @@ PRIVATE void test_event(void)
if (mthread_event_wait(NULL) == 0) err(23, 2); if (mthread_event_wait(NULL) == 0) err(23, 2);
if (mthread_event_fire(NULL) == 0) err(23, 3); 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[0], NULL, event_a, NULL) != 0) err(23, 4);
if (mthread_create(&t[1], NULL, event_b, NULL) != 0) err(23, 5); if (mthread_create(&t[1], NULL, event_b, NULL) != 0) err(23, 5);
/* wait for them to block on event */
mthread_yield_all(); mthread_yield_all();
VERIFY_EVENT(0, 0, 23, 6); VERIFY_EVENT(0, 0, 23, 6);
/* Fire event to wakeup thread a */
if (mthread_event_fire(&event) != 0) err(23, 7); if (mthread_event_fire(&event) != 0) err(23, 7);
mthread_yield_all(); 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++) 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);
} }
/*===========================================================================* /*===========================================================================*