--- include/asm-sim/system.h | 4 ++++ include/asm-uvm/system.h | 4 ++++ include/nucleus/timer.h | 7 ++----- ksrc/drivers/testing/timerbench.c | 7 ++++--- ksrc/nucleus/pod.c | 2 +- ksrc/nucleus/thread.c | 12 ++++++------ ksrc/nucleus/timer.c | 13 ++++--------- ksrc/skins/native/alarm.c | 6 +++--- ksrc/skins/posix/timer.c | 7 ++++--- ksrc/skins/psos+/tm.c | 6 +++--- ksrc/skins/vxworks/defs.h | 3 +++ ksrc/skins/vxworks/wdLib.c | 11 ++++++++++- sim/skins/posix/testsuite/xntest.c | 4 ++-- sim/skins/vxworks/testsuite/xntest.c | 4 ++-- 14 files changed, 52 insertions(+), 38 deletions(-) Index: include/asm-sim/system.h =================================================================== --- include/asm-sim/system.h.orig +++ include/asm-sim/system.h @@ -245,6 +245,10 @@ xnarch_read_environ (const char *name, c #define __init #define __exit +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + #ifdef __cplusplus extern "C" { #endif Index: include/asm-uvm/system.h =================================================================== --- include/asm-uvm/system.h.orig +++ include/asm-uvm/system.h @@ -52,6 +52,10 @@ #define __init #define __exit +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + typedef int spl_t; typedef unsigned long cpumask_t; Index: include/nucleus/timer.h =================================================================== --- include/nucleus/timer.h.orig +++ include/nucleus/timer.h @@ -226,9 +226,7 @@ typedef struct xntimer { struct xnsched *sched; /* !< Sched structure to which the timer is attached. */ - void (*handler)(void *cookie); /* !< Timeout handler. */ - - void *cookie; /* !< Cookie to pass to the timeout handler. */ + void (*handler)(struct xntimer *timer); /* !< Timeout handler. */ XNARCH_DECL_DISPLAY_CONTEXT(); @@ -288,8 +286,7 @@ extern "C" { extern xntmops_t *nktimer; void xntimer_init(xntimer_t *timer, - void (*handler)(void *cookie), - void *cookie); + void (*handler)(xntimer_t *timer)); void xntimer_destroy(xntimer_t *timer); Index: ksrc/drivers/testing/timerbench.c =================================================================== --- ksrc/drivers/testing/timerbench.c.orig +++ ksrc/drivers/testing/timerbench.c @@ -165,9 +165,10 @@ void timer_task_proc(void *arg) } -void timer_proc(void *arg) +void timer_proc(xntimer_t *timer) { - struct rt_tmbench_context *ctx = (struct rt_tmbench_context *)arg; + struct rt_tmbench_context *ctx = + container_of(timer, struct rt_tmbench_context, timer); eval_inner_loop(ctx, (long)(rtdm_clock_read() - ctx->date)); @@ -309,7 +310,7 @@ int rt_tmbench_ioctl_nrt(struct rtdm_dev } } else { /* FIXME: convert to RTDM timers */ - xntimer_init(&ctx->timer, timer_proc, ctx); + xntimer_init(&ctx->timer, timer_proc); ctx->curr.test_loops = 0; Index: ksrc/nucleus/pod.c =================================================================== --- ksrc/nucleus/pod.c.orig +++ ksrc/nucleus/pod.c @@ -390,7 +390,7 @@ int xnpod_init(xnpod_t *pod, int minpri, /* No direct handler here since the host timer processing is postponed to xnintr_irq_handler(), as part of the interrupt exit code. */ - xntimer_init(&pod->htimer, NULL, NULL); + xntimer_init(&pod->htimer, NULL); xntimer_set_priority(&pod->htimer, XNTIMER_LOPRIO); xnlock_put_irqrestore(&nklock, s); Index: ksrc/nucleus/thread.c =================================================================== --- ksrc/nucleus/thread.c.orig +++ ksrc/nucleus/thread.c @@ -25,16 +25,16 @@ #include #include -static void xnthread_timeout_handler(void *cookie) +static void xnthread_timeout_handler(xntimer_t *timer) { - xnthread_t *thread = (xnthread_t *)cookie; + xnthread_t *thread = container_of(timer, xnthread_t, rtimer); __setbits(thread->status, XNTIMEO); /* Interrupts are off. */ xnpod_resume_thread(thread, XNDELAY); } -static void xnthread_periodic_handler(void *cookie) +static void xnthread_periodic_handler(xntimer_t *timer) { - xnthread_t *thread = (xnthread_t *)cookie; + xnthread_t *thread = container_of(timer, xnthread_t, ptimer); if (xnthread_test_flags(thread, XNDELAY)) /* Prevent unwanted round-robin. */ xnpod_resume_thread(thread, XNDELAY); @@ -46,9 +46,9 @@ int xnthread_init(xnthread_t *thread, { int err; - xntimer_init(&thread->rtimer, &xnthread_timeout_handler, thread); + xntimer_init(&thread->rtimer, &xnthread_timeout_handler); xntimer_set_priority(&thread->rtimer, XNTIMER_HIPRIO); - xntimer_init(&thread->ptimer, &xnthread_periodic_handler, thread); + xntimer_init(&thread->ptimer, &xnthread_periodic_handler); xntimer_set_priority(&thread->ptimer, XNTIMER_HIPRIO); /* Setup the TCB. */ Index: ksrc/nucleus/timer.c =================================================================== --- ksrc/nucleus/timer.c.orig +++ ksrc/nucleus/timer.c @@ -212,7 +212,7 @@ static void xntimer_do_tick_aperiodic(vo if (timer != &nkpod->htimer) { if (!testbits(nkpod->status, XNTLOCK)) { - timer->handler(timer->cookie); + timer->handler(timer); if (timer->interval == XN_INFINITE || !testbits(timer->status, XNTIMER_DEQUEUED) @@ -388,7 +388,7 @@ static void xntimer_do_tick_periodic(voi if (timer != &nkpod->htimer) { if (!testbits(nkpod->status, XNTLOCK)) { - timer->handler(timer->cookie); + timer->handler(timer); if (timer->interval == XN_INFINITE || !testbits(timer->status, XNTIMER_DEQUEUED) @@ -461,7 +461,7 @@ void xntimer_set_periodic_mode(void) #endif /* CONFIG_XENO_OPT_TIMING_PERIODIC */ /*! - * \fn void xntimer_init(xntimer_t *timer,void (*handler)(void *cookie),void *cookie) + * \fn void xntimer_init(xntimer_t *timer,void (*handler)(xntimer_t *timer)) * \brief Initialize a timer object. * * Creates a timer. When created, a timer is left disarmed; it must be @@ -474,9 +474,6 @@ void xntimer_set_periodic_mode(void) * * @param handler The routine to call upon expiration of the timer. * - * @param cookie A user-defined opaque cookie the nucleus will pass - * unmodified to the handler as its unique argument. - * * There is no limitation on the number of timers which can be * created/active concurrently. * @@ -492,8 +489,7 @@ void xntimer_set_periodic_mode(void) * Rescheduling: never. */ -void xntimer_init(xntimer_t *timer, - void (*handler) (void *cookie), void *cookie) +void xntimer_init(xntimer_t *timer, void (*handler) (xntimer_t *timer)) { /* CAUTION: Setup from xntimer_init() must not depend on the periodic/aperiodic timing mode. */ @@ -507,7 +503,6 @@ void xntimer_init(xntimer_t *timer, xntimer_set_priority(timer, XNTIMER_STDPRIO); timer->status = XNTIMER_DEQUEUED; timer->handler = handler; - timer->cookie = cookie; timer->interval = 0; timer->sched = xnpod_current_sched(); Index: ksrc/skins/native/alarm.c =================================================================== --- ksrc/skins/native/alarm.c.orig +++ ksrc/skins/native/alarm.c @@ -117,9 +117,9 @@ void __native_alarm_pkg_cleanup(void) { } -static void __alarm_trampoline(void *cookie) +static void __alarm_trampoline(xntimer_t *timer) { - RT_ALARM *alarm = (RT_ALARM *)cookie; + RT_ALARM *alarm = container_of(timer, RT_ALARM, timer_base); ++alarm->expiries; alarm->handler(alarm, alarm->cookie); } @@ -189,7 +189,7 @@ int rt_alarm_create(RT_ALARM *alarm, if (xnpod_asynch_p()) return -EPERM; - xntimer_init(&alarm->timer_base, &__alarm_trampoline, alarm); + xntimer_init(&alarm->timer_base, &__alarm_trampoline); alarm->handle = 0; /* i.e. (still) unregistered alarm. */ alarm->magic = XENO_ALARM_MAGIC; alarm->expiries = 0; Index: ksrc/skins/posix/timer.c =================================================================== --- ksrc/skins/posix/timer.c.orig +++ ksrc/skins/posix/timer.c @@ -52,9 +52,10 @@ static xnqueue_t timer_freeq; static struct pse51_timer timer_pool[PSE51_TIMER_MAX]; -static void pse51_base_timer_handler(void *cookie) +static void pse51_base_timer_handler(xntimer_t *xntimer) { - struct pse51_timer *timer = (struct pse51_timer *)cookie; + struct pse51_timer *timer = + container_of(xntimer, struct pse51_timer, timerbase); if (timer->queued) { if (timer->overruns < DELAYTIMER_MAX) @@ -166,7 +167,7 @@ int timer_create(clockid_t clockid, timer->si.info.si_value.sival_int = (timer - timer_pool); } - xntimer_init(&timer->timerbase, &pse51_base_timer_handler, timer); + xntimer_init(&timer->timerbase, &pse51_base_timer_handler); timer->overruns = 0; timer->owner = NULL; Index: ksrc/skins/psos+/tm.c =================================================================== --- ksrc/skins/psos+/tm.c.orig +++ ksrc/skins/psos+/tm.c @@ -57,9 +57,9 @@ void tm_destroy_internal(psostm_t *tm) xnfree(tm); } -static void tm_evpost_handler(void *cookie) +static void tm_evpost_handler(xntimer_t *timer) { - psostm_t *tm = (psostm_t *)cookie; + psostm_t *tm = container_of(timer, psostm_t, timerbase); ev_send((u_long)tm->owner, tm->events); @@ -83,7 +83,7 @@ static u_long tm_start_event_timer(u_lon tm->owner = psos_current_task(); *tmid = (u_long)tm; - xntimer_init(&tm->timerbase, tm_evpost_handler, tm); + xntimer_init(&tm->timerbase, tm_evpost_handler); tm->magic = PSOS_TM_MAGIC; xnlock_get_irqsave(&nklock, s); Index: ksrc/skins/vxworks/defs.h =================================================================== --- ksrc/skins/vxworks/defs.h.orig +++ ksrc/skins/vxworks/defs.h @@ -139,6 +139,9 @@ typedef struct wind_wd { xntimer_t timerbase; + wind_timer_t handler; + long arg; + #ifdef CONFIG_XENO_OPT_REGISTRY xnhandle_t handle; char name[XNOBJECT_NAME_LEN]; Index: ksrc/skins/vxworks/wdLib.c =================================================================== --- ksrc/skins/vxworks/wdLib.c.orig +++ ksrc/skins/vxworks/wdLib.c @@ -90,6 +90,13 @@ static xnpnode_t wd_pnode = { #endif /* CONFIG_XENO_EXPORT_REGISTRY */ +static void wind_wd_trampoline(xntimer_t *timer) +{ + wind_wd_t *wd = container_of(timer, wind_wd_t, timerbase); + + wd->handler(wd->arg); +} + void wind_wd_init(void) { initq(&wind_wd_q); @@ -172,7 +179,9 @@ STATUS wdStart(WDOG_ID wdog_id, int time else xntimer_stop(&wd->timerbase); - xntimer_init(&wd->timerbase, (void (*)(void *))handler, (void *)arg); + xntimer_init(&wd->timerbase, wind_wd_trampoline); + wd->handler = handler; + wd->arg = arg; xntimer_start(&wd->timerbase, timeout, XN_INFINITE); Index: sim/skins/posix/testsuite/xntest.c =================================================================== --- sim/skins/posix/testsuite/xntest.c.orig +++ sim/skins/posix/testsuite/xntest.c @@ -63,7 +63,7 @@ static inline int strings_differ(const c return ((!str1 || !str2) ? str1!=str2 : strcmp(str1, str2)); } -static void interrupt_test (void *dummy) +static void interrupt_test (xntimer_t *dummy) { xnpod_fatal("\ntest interrupted by watchdog.\n"); } @@ -78,7 +78,7 @@ void xntest_start(void) xntest_verbose = module_param_value(xntest_verbose); xnlock_get_irqsave(&test_lock, s); - xntimer_init(&watchdog, interrupt_test, 0); + xntimer_init(&watchdog, interrupt_test); xntimer_start(&watchdog, xnpod_ns2ticks(test_timeout * 1000000000ULL), XN_INFINITE); initq(&marks_q); Index: sim/skins/vxworks/testsuite/xntest.c =================================================================== --- sim/skins/vxworks/testsuite/xntest.c.orig +++ sim/skins/vxworks/testsuite/xntest.c @@ -63,7 +63,7 @@ static inline int strings_differ(const c return ((!str1 || !str2) ? str1!=str2 : strcmp(str1, str2)); } -static void interrupt_test (void *dummy) +static void interrupt_test (xntimer_t *dummy) { xnpod_fatal("\ntest interrupted by watchdog.\n"); } @@ -78,7 +78,7 @@ void xntest_start(void) xntest_verbose = module_param_value(xntest_verbose); xnlock_get_irqsave(&test_lock, s); - xntimer_init(&watchdog, interrupt_test, 0); + xntimer_init(&watchdog, interrupt_test); xntimer_start(&watchdog, xnpod_ns2ticks(test_timeout * 1000000000ULL), XN_INFINITE); initq(&marks_q);