support non-timed eventflag

This commit is contained in:
NIIBE Yutaka
2013-06-19 13:56:25 +09:00
parent d77204c7d5
commit 0913c0d109
2 changed files with 53 additions and 12 deletions

View File

@@ -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);
}

View File

@@ -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);