support non-timed eventflag
This commit is contained in:
58
eventflag.c
58
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user