diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2013-06-19 13:56:25 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2013-06-19 13:56:25 +0900 |
commit | 0913c0d109ab924e9c89b8064ac84d9d34d52360 (patch) | |
tree | 868654b5f4d516c81843d685585518112d641f07 | |
parent | d77204c7d536806f66d3ad0e477e8039ff441681 (diff) |
support non-timed eventflag
-rw-r--r-- | eventflag.c | 58 | ||||
-rw-r--r-- | eventflag.h | 7 |
2 files changed, 53 insertions, 12 deletions
diff --git a/eventflag.c b/eventflag.c index 658c779..c363d58 100644 --- a/eventflag.c +++ b/eventflag.c @@ -1,5 +1,5 @@ /* - * eventflag.c - Eventflag with timeout + * eventflag.c - Eventflag with/without timeout * * Copyright (C) 2013 Flying Stone Technology * Author: NIIBE Yutaka <gniibe@fsij.org> @@ -31,31 +31,64 @@ #include <chopstx.h> #include <eventflag.h> +enum { + EVENTFLAG_ERR_WAIT = CHOPSTX_ERR_JOIN + 1, + EVENTFLAG_ERR_TIMED_WAIT, +}; + + void -eventflag_init (struct event_flag *ev, chopstx_t owner) +eventflag_init (struct event_flag *ev, chopstx_t sleeper) { - ev->owner = owner; - ev->wait_usec = 0; + ev->sleeper = sleeper; + + if (sleeper) + ev->u.wait_usec = 0; + else + chopstx_cond_init (&ev->u.cond); + ev->flag = 0; chopstx_mutex_init (&ev->mutex); } eventmask_t +eventflag_wait (struct event_flag *ev) +{ + int n; + + if (ev->sleeper) + chx_fatal (EVENTFLAG_ERR_WAIT); + + chopstx_mutex_lock (&ev->mutex); + if (!ev->flag) + chopstx_cond_wait (&ev->cond, &ev->mutex); + + n = __builtin_ffs ((ev->flag & m)); + ev->flag &= ~(1 << (n - 1)); + chopstx_mutex_unlock (&ev->mutex); + + return (1 << (n - 1)); +} + +eventmask_t eventflag_wait_timeout (struct event_flag *ev, uint32_t usec) { eventmask_t em = 0; int n; + if (ev->sleeper == 0) + chx_fatal (EVENTFLAG_ERR_TIMED_WAIT); + chopstx_mutex_lock (&ev->mutex); if (!ev->flag) { - ev->wait_usec = usec; + ev->u.wait_usec = usec; chopstx_mutex_unlock (&ev->mutex); - chopstx_usec_wait_var (&ev->wait_usec); + chopstx_usec_wait_var (&ev->u.wait_usec); chopstx_mutex_lock (&ev->mutex); - ev->wait_usec = 0; + ev->u.wait_usec = 0; } n = __builtin_ffs (ev->flag); @@ -75,10 +108,15 @@ eventflag_signal (struct event_flag *ev, eventmask_t m) { chopstx_mutex_lock (&ev->mutex); ev->flag |= m; - if (ev->wait_usec) + if (ev->sleeper) { - ev->wait_usec = 0; - chopstx_wakeup_usec_wait (ev->owner); + if (ev->u.wait_usec) + { + ev->u.wait_usec = 0; + chopstx_wakeup_usec_wait (ev->sleeper); + } } + else + chopstx_cond_signal (&ev->cond); chopstx_mutex_unlock (&ev->mutex); } diff --git a/eventflag.h b/eventflag.h index 0b595b8..ce109f3 100644 --- a/eventflag.h +++ b/eventflag.h @@ -1,10 +1,13 @@ typedef uint32_t eventmask_t; struct eventflag { - chopstx_t owner; - uint32_t wait_usec; + chopstx_t sleeper; eventmask_t flag; chopstx_mutex_t mutex; + union { + uint32_t wait_usec; + chopstx_cond_t cond; + } u; }; void eventflag_init (struct eventflag *ev, chopstx_t owner); |