From acc2a645a748497ba85d7d1763a84006b93dac3c Mon Sep 17 00:00:00 2001 From: Till Straumann Date: Thu, 23 Apr 2009 04:26:07 +0000 Subject: - callout_stop() and callout_reset() actually must return an 'int' value indicating whether a callout was pending. - added callout_active(), callout_pending(), callout_deactivate(). --- bsd_eth_drivers/libbsdport/callout.h | 44 ++++++++++++++++++++++++++++-- bsd_eth_drivers/libbsdport/rtems_callout.c | 26 ++++++++++++++---- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/bsd_eth_drivers/libbsdport/callout.h b/bsd_eth_drivers/libbsdport/callout.h index 3f586bf..acc9de0 100644 --- a/bsd_eth_drivers/libbsdport/callout.h +++ b/bsd_eth_drivers/libbsdport/callout.h @@ -18,16 +18,56 @@ struct callout { void *c_arg; struct mtx *c_mtx; callout_time_t c_time; + unsigned c_flags; }; +#define CALLOUT_PENDING (1<<0) +#define CALLOUT_ACTIVE (1<<1) + +/* + * Strictly, we don't need any protection + * because the global network semaphore + * takes care; however we want to + */ +static inline int +callout_active(struct callout *p_c) +{ +int rval; +rtems_interrupt_level l; + rtems_interrupt_disable(l); + rval = p_c->c_flags & CALLOUT_ACTIVE; + rtems_interrupt_enable(l); + return rval; +} + +static inline int +callout_pending(struct callout *p_c) +{ +int rval; +rtems_interrupt_level l; + rtems_interrupt_disable(l); + rval = p_c->c_flags & CALLOUT_PENDING; + rtems_interrupt_enable(l); + return rval; +} + +static inline void +callout_decativate(struct callout *p_c) +{ +rtems_interrupt_level l; + rtems_interrupt_disable(l); + p_c->c_flags &= ~CALLOUT_ACTIVE; + rtems_interrupt_enable(l); +} + /* We cannot stop a callout that's in progress */ -void +int callout_stop(struct callout *c); #define callout_drain callout_stop -void +int callout_reset(struct callout *c, int ticks, void (*fn)(void*), void *arg); void diff --git a/bsd_eth_drivers/libbsdport/rtems_callout.c b/bsd_eth_drivers/libbsdport/rtems_callout.c index ce9a477..de1df83 100644 --- a/bsd_eth_drivers/libbsdport/rtems_callout.c +++ b/bsd_eth_drivers/libbsdport/rtems_callout.c @@ -100,6 +100,9 @@ LIST_KEY_DECL(k); n = c->c_next; if ( c->c_time <= 0 ) { /* this one expired */ + rtems_interrupt_disable(k1); + c->c_flags &= ~ CALLOUT_PENDING; + rtems_interrupt_enable(k1); c_deq(c); if ( c->c_func ) c->c_func(c->c_arg); @@ -173,31 +176,38 @@ bail: /* We cannot stop a callout that's in progress */ -void +int callout_stop(struct callout *c) { +rtems_interrupt_level l; LIST_KEY_DECL(k); if ( !c->c_pprev ) - return; /* not currently on a list */ + return 0; /* not currently on a list */ LIST_LOCK(k); /* remove from list */ c_deq(c); + rtems_interrupt_disable(l); + c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING); + rtems_interrupt_enable(l); LIST_UNLOCK(k); + + return 1; } -void +int callout_reset(struct callout *c, int ticks, timeout_t fn, void *arg) { +rtems_interrupt_level l; LIST_KEY_DECL(k); -int i; +int i, rval; if ( ticks <= 0 ) ticks = 1; - callout_stop(c); + rval = callout_stop(c); c->c_func = fn; c->c_arg = arg; @@ -209,7 +219,13 @@ int i; /* enqueue */ c_enq(&c_wheel[i], c); + rtems_interrupt_disable(l); + c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING); + rtems_interrupt_enable(l); + LIST_UNLOCK(k); + + return rval; } static rtems_id callout_tid = 0; -- cgit v1.2.3