chevents: listener flags clearing (bug)

Discussions and support about ChibiOS/RT, the free embedded RTOS.
Stapelzeiger
Posts: 7
Joined: Mon Apr 06, 2015 1:08 pm

chevents: listener flags clearing (bug)

Post by Stapelzeiger »

Hi,

When using chEvtBroadcastFlags the event flags (el_flags) of a event_listener_t are not cleared automatically when the event is triggered.
The problem is that this results in incorrect behaviour for functions that work with eventmasks, like chEvtGetAndClearEvents. This function can actually return the same event multiple times without the event source (event_source_t) triggering the corresponding flag more than once. This is a bug.

The issue comes from the fact that the flags are not cleared in the listener. This causes the listener to re-trigger an event whenever the event source broadcasts any flag, regardless of the wflags mask in the listener.
Only chEvtGetAndClearFlags provides correct clearing & returning of the triggered flags.

Since this behaviour is not documented anywhere (as far as I could find), this is a serious issue.

Best regards
Patrick
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: chevents: listener flags clearing (bug)

Post by Giovanni »

HI,

The listening thread is meant to call chEvtGetAndClearFlags() in order to get and clear them, this is intentional.

All the event wait functions know nothing about the listener structure(s) so it can't be done in that context (there is no way starting from a thread to enumerate all the listener structures associated to the thread, the association is mono-directional listeners->thread, thread->listeners is not possible).

The broadcast function only sees that there are pending flags that are part of the wanted flags (el_wflags) so it signals the thread unless the flags are cleared.

Giovanni
Stapelzeiger
Posts: 7
Joined: Mon Apr 06, 2015 1:08 pm

Re: chevents: listener flags clearing (bug)

Post by Stapelzeiger »

The point is that the function chEvtGetAndClearEvents doesn't do what it says i.e. clear the event, since it is retriggered as soon as the source broadcasts anything. This is very unintuitive and not documented.

For the implementation details: I see that the thread can't enumerate the listeners, but the broadcast function could still clear the flags as soon as it wakes up the thread (and maybe store a copy if needed for readout later, for the chEvtGetAndClearFlags API).
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: chevents: listener flags clearing (bug)

Post by Giovanni »

Wait, there are two kind of flags there:

1) Events Mask (eventmask_t), this is a per-thread mask and is cleared inside the "wait" functions. The function returns the cleared flags.
2) Event Flags (evenflags_t), this is information generated by sources and is accumulated (ORed) inside the listener structures. This has to be cleared as an acknowledge by chEvtGetAndClearFlags() or you will be notified again.

Are you referring to 1 or 2?

chEvtGetAndClearEvents() clears the type 1 and seldom used, it can be used in order to start from a clean state.

Giovanni
Stapelzeiger
Posts: 7
Joined: Mon Apr 06, 2015 1:08 pm

Re: chevents: listener flags clearing (bug)

Post by Stapelzeiger »

1) doesn't really clear the event (yes, sure it clears the event in the thread, but this isn't really anything useful).
2) does what it says.

The thing is that when working with event masks (eventmask_t) the function chEvtGetAndClearEvents doesn't clear the event at the listener. So you have to call chEvtGetAndClearFlags to really clear the event. This is not the behaviour one would expect and doesn't seem to be documented. I'm sure that I'm not the only one who misunderstood that bit, since it is only evident when reading the implementation of chflags.

I looked quickly through the code again. What I suggest is that as soon as the event flags (el_flags) in the listener match the mask (el_wflags) the el_flags are cleared and an event is generated for the task. This should result in expected behaviour for the chEvtGetAndClearEvents & chEvtWait* functions.
To keep the current behaviour of the chEvtGetAndClearFlags API the el_flags could be copied in the listener before being cleared. Then the chEvtGetAndClearFlags could return the (el_flags | el_flags_copy) and clear both.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: chevents: listener flags clearing (bug)

Post by Giovanni »

Hi,

Consider that events and event flags are two distinct things. It is possible to work with events without having to use event flags.

Consider this scenario: a thread is signaled directly using chEvtSignal(), this only use events, event flags are not used at all, why should chEvtGetAndClearEvents() clear also flags? there aren't listener nor flags involved.

Flags are only part of the (optional) broadcasting mechanism, this is why you won't see any handling of those in those functions only dealing with events. Flags are only handled in the context of the event_listener_t object.

I can agree documentation could be better, for some reason I seem to be unable to fully explain the mechanism.

Giovanni
Stapelzeiger
Posts: 7
Joined: Mon Apr 06, 2015 1:08 pm

Re: chevents: listener flags clearing (bug)

Post by Stapelzeiger »

Consider that events and event flags are two distinct things. It is possible to work with events without having to use event flags.

I got that.
why should chEvtGetAndClearEvents() clear also flags?

I don't want the function to actually go and clear flags in the listeners. This would not respect the separation between flags and events, and besides it would be hard to implement.
What I suggest is that the listener clears its own flags as soon as it has notified the thread (using chEvtSignal) so that it won't signal the thread again for the same flag.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: chevents: listener flags clearing (bug)

Post by Giovanni »

OK, and how the thread would know which flags were involved if those have been cleared?

Giovanni
Stapelzeiger
Posts: 7
Joined: Mon Apr 06, 2015 1:08 pm

Re: chevents: listener flags clearing (bug)

Post by Stapelzeiger »

you could create a copy inside the listener. (what i suggested in my comment above to keep the existing flags API)
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: chevents: listener flags clearing (bug)

Post by Giovanni »

That would increase the size of the listener and I need a good reason for increasing RAM usage and breaking compatibility.

It is not a bug anyway, it is working as intended.

Giovanni
Post Reply