summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2013-06-19 13:56:25 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2013-06-19 13:56:25 +0900
commit0913c0d109ab924e9c89b8064ac84d9d34d52360 (patch)
tree868654b5f4d516c81843d685585518112d641f07
parentd77204c7d536806f66d3ad0e477e8039ff441681 (diff)
support non-timed eventflag
-rw-r--r--eventflag.c58
-rw-r--r--eventflag.h7
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);