From 0e3b7c98f5b8fb6f71e431791789c9370a8ae89f Mon Sep 17 00:00:00 2001 From: arighi Date: Tue, 26 Oct 2010 08:44:04 +0000 Subject: [PATCH] mware: fix generic completion events behaviour without the kernel The correct behaviour of the generic completion events is to allow any process to wait for the event and not only the one that initialized the completion. With this fix the "owner" of the completion is assigned when a process call event_wait() and not event_initGeneric(). In this way a call to event_do() correctly wakes up the process that actually performed the event_wait(). Moreover, use the signal SIG_SYSTEM5 for generic completion events (instead of SIG_SINGLE, that is already by the timer and msg). git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4463 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/mware/event.c | 2 ++ bertos/mware/event.h | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/bertos/mware/event.c b/bertos/mware/event.c index 24d73d93..567e18a9 100644 --- a/bertos/mware/event.c +++ b/bertos/mware/event.c @@ -60,11 +60,13 @@ void event_hook_softint(Event *e) void event_hook_generic(Event *e) { e->Ev.Gen.completed = true; + MEMORY_BARRIER; } #if CONFIG_TIMER_EVENTS void event_hook_generic_timeout(Event *e) { e->Ev.Gen.completed = true; + MEMORY_BARRIER; } #endif diff --git a/bertos/mware/event.h b/bertos/mware/event.h index fcdb90fb..83f0e13e 100644 --- a/bertos/mware/event.h +++ b/bertos/mware/event.h @@ -149,7 +149,7 @@ INLINE Event event_createSignal(struct Process *proc, sigbit_t bit) #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS /** Initialize the generic sleepable event \a e */ #define event_initGeneric(e) \ - event_initSignal(e, proc_current(), SIG_SINGLE) + event_initSignal(e, proc_current(), SIG_SYSTEM5) #else #define event_initGeneric(e) \ ((e)->action = event_hook_generic, (e)->Ev.Gen.completed = false) @@ -173,10 +173,13 @@ INLINE Event event_createGeneric(void) INLINE void event_wait(Event *e) { #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS + e->Ev.Sig.sig_proc = proc_current(); sig_wait(e->Ev.Sig.sig_bit); #else while (ACCESS_SAFE(e->Ev.Gen.completed) == false) cpu_relax(); + e->Ev.Gen.completed = false; + MEMORY_BARRIER; #endif } @@ -193,16 +196,21 @@ INLINE void event_wait(Event *e) INLINE bool event_waitTimeout(Event *e, ticks_t timeout) { #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS + e->Ev.Sig.sig_proc = proc_current(); return (sig_waitTimeout(e->Ev.Sig.sig_bit, timeout) & SIG_TIMEOUT) ? false : true; #else ticks_t end = timer_clock() + timeout; + bool ret; while ((ACCESS_SAFE(e->Ev.Gen.completed) == false) || TIMER_AFTER(timer_clock(), end)) cpu_relax(); + ret = e->Ev.Gen.completed; + e->Ev.Gen.completed = false; + MEMORY_BARRIER; - return e->Ev.Gen.completed; + return ret; #endif } #endif /* CONFIG_TIMER_EVENTS */ -- 2.25.1