mware: fix generic completion events behaviour without the kernel
authorarighi <arighi@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 26 Oct 2010 08:44:04 +0000 (08:44 +0000)
committerarighi <arighi@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 26 Oct 2010 08:44:04 +0000 (08:44 +0000)
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
bertos/mware/event.h

index 24d73d93f7f678371b2e4b3e17ef346d9d3c616a..567e18a9a42ceaed9b907ec3ed7853bddbfa684d 100644 (file)
@@ -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
index fcdb90fbcc986db760725dc279464ed7d4d3ddea..83f0e13eff995182c2a18c1faa1a293f203963f7 100644 (file)
@@ -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 */