From 6aebe0e6d7a5be5aacda0b39d86b4a9b421e247c Mon Sep 17 00:00:00 2001 From: arighi Date: Thu, 3 Mar 2011 16:24:18 +0000 Subject: [PATCH] events: fix signal overlapping in generic events When the kernel is enabled the generic events subsystem uses SIG_SYSTEM5 to synchronize the completion of the events. The owner (process) of an event is assigned when the event is initialized via event_initGeneric(). It may happen that the same process initializes more than one event, so when one of them is triggered the process is awakened independently on the event it is waiting for. Fix this by moving the signal masks into the generic event structure and export a new signal API to directly accept the signal masks, instead of implicitly using the signal masks of the current process. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4750 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/mware/event.c | 7 +++++++ bertos/mware/event.h | 23 +++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/bertos/mware/event.c b/bertos/mware/event.c index 567e18a9..489014db 100644 --- a/bertos/mware/event.c +++ b/bertos/mware/event.c @@ -50,6 +50,13 @@ void event_hook_signal(Event *e) { sig_post((e)->Ev.Sig.sig_proc, (e)->Ev.Sig.sig_bit); } + +void event_hook_generic_signal(Event *e) +{ + sig_postSignal(&e->Ev.SigGen.sig, + e->Ev.SigGen.sig_proc, + EVENT_GENERIC_SIGNAL); +} #endif void event_hook_softint(Event *e) diff --git a/bertos/mware/event.h b/bertos/mware/event.h index 0a87af1a..3d006059 100644 --- a/bertos/mware/event.h +++ b/bertos/mware/event.h @@ -123,6 +123,12 @@ typedef struct Event struct Process *sig_proc; /* Process to be signalled */ sigbit_t sig_bit; /* Signal to send */ } Sig; + + struct + { + struct Process *sig_proc; /* Process to be signalled */ + Signal sig; /* Signal structure */ + } SigGen; #endif struct { @@ -141,6 +147,7 @@ void event_hook_ignore(Event *event); void event_hook_signal(Event *event); void event_hook_softint(Event *event); void event_hook_generic(Event *event); +void event_hook_generic_signal(Event *event); void event_hook_generic_timeout(Event *event); /** Initialize the event \a e as a no-op */ @@ -190,13 +197,20 @@ 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_SYSTEM5) +#define event_initGeneric(e) \ + ((e)->action = event_hook_generic_signal, \ + (e)->Ev.SigGen.sig_proc = proc_current(), \ + (e)->Ev.SigGen.sig.wait = 0, (e)->Ev.SigGen.sig.recv = 0) #else #define event_initGeneric(e) \ ((e)->action = event_hook_generic, (e)->Ev.Gen.completed = false) #endif +/** + * Signal used to implement generic events. + */ +#define EVENT_GENERIC_SIGNAL SIG_SYSTEM5 + /** * Create a generic sleepable event. * @@ -220,7 +234,7 @@ 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); + sig_waitSignal(&e->Ev.SigGen.sig, EVENT_GENERIC_SIGNAL); #else while (ACCESS_SAFE(e->Ev.Gen.completed) == false) cpu_relax(); @@ -247,7 +261,8 @@ INLINE bool event_waitTimeout(Event *e, ticks_t timeout) #if defined(CONFIG_KERN_SIGNALS) && CONFIG_KERN_SIGNALS e->Ev.Sig.sig_proc = proc_current(); - ret = (sig_waitTimeout(e->Ev.Sig.sig_bit, timeout) & SIG_TIMEOUT) ? + ret = (sig_waitTimeoutSignal(&e->Ev.SigGen.sig, + EVENT_GENERIC_SIGNAL, timeout) & SIG_TIMEOUT) ? false : true; #else ticks_t end = timer_clock() + timeout; -- 2.25.1