Skip to content

events: Fix zero wait condition in non-rtos semaphore #3991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 19, 2017

Conversation

geky
Copy link
Contributor

@geky geky commented Mar 22, 2017

Before, if the semaphore recieved a wait of zero, the semaphore would erronously drop the ticker event to wake up the device, causing the device to go to sleep without any mechanism to wake itself up.

During a dispatch operation, the event queue dispatches all events that have expired, so the call to equeue_sema_wait very rarely has a wait of zero. But this can happen when an event is posted just after a dispatch has occured.

The rtos version handles this correctly:
https://github.com/ARMmbed/mbed-os/blob/master/events/equeue/equeue_mbed.cpp#L105

related issue #3857
cc @pan-, @tbondar, @nvlsianpu

@geky geky mentioned this pull request Mar 22, 2017
@pan-
Copy link
Member

pan- commented Mar 23, 2017

@geky Good catch, I'll test if it solves the issue but there is others in the ticker code.

@@ -131,7 +131,7 @@ static void equeue_sema_timeout(equeue_sema_t *s) {
bool equeue_sema_wait(equeue_sema_t *s, int ms) {
int signal = 0;
Timeout timeout;
if (ms > 0) {
if (ms >= 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried of what can happen with a delay of 0 us.
The timestamp is computed from the current time (here) and there is good chances that it will be in the past (or a far future!) when it will be actually set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that's a good point. Do you think we should clamp it to 1 millisecond to be safe?

It does look like timer events in the past are handled correctly (in common code):

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be reasonable to apply the same behaviour as the one used by RTX semaphore:

when millisec is 0, the function returns instantly.

see http://www.keil.com/pack/doc/CMSIS/RTOS/html/group__CMSIS__RTOS__SemaphoreMgmt.html#gacc15b0fc8ce1167fe43da33042e62098

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be reasonable to apply the same behaviour as the one used by RTX semaphore:

What do you think @geky ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is the current behaviour of this pr. When ms is 0, the ticker attach should interrupt immediately and set the flag to 1, causing the following while loop (here) to exit immediately.

Do you think the zero case behaviour should be explicit?

-    if (ms > 0) {
+    if (ms == 0) {
+        return false;
+    } else if (ms > 0) {
         timeout.attach_us(callback(equeue_sema_timeout, s), ms*1000);
     }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@geky Yes I think that if ms is 0 then the function should returns instantly. The current version is more like osThreadYield followed by a return when the task is rescheduled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pan-, should be updated. At the very least this makes the less travelled code path clearer.

@geky geky force-pushed the fix-events-non-rtos-wait branch from d836520 to 3f32163 Compare April 5, 2017 20:28
@geky
Copy link
Contributor Author

geky commented Apr 5, 2017

@pan-, should be updated, let me know if you still have concerns. At the very least this makes the less travelled code path clearer.

if (ms > 0) {
if (ms == 0) {
return false;
} else if (ms >= 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a blocker for the PR, but it strictly greater than 0 might be clearer.
i also wonder what should happen when ms is less than 0 ?
Is it expected that the semaphore will put the system to sleep without timeout ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable.

Throughout the equeue library a timeout of -1 is used to represent an infinite wait, so here any negative value would indicate that the semaphore waits forever.

I added a bit of clarification to the function declaration since it's easy to miss that corner case at this level: https://github.com/ARMmbed/mbed-os/pull/3991/files#diff-224d7ae23d9d5591b6a59537012c82d9

Before, if the semaphore recieved a wait of zero, the semaphore
would erronously drop the ticker event to wake up the device,
causing the device to go to sleep without any mechanism to wake
itself up.

During a dispatch operation, the event queue dispatches all events
that have expired, so the call to equeue_sema_wait very rarely
has a wait of zero. But this can happen when an event is posted
just after a dispatch has occured.
@geky geky force-pushed the fix-events-non-rtos-wait branch from 3f32163 to 2bcb095 Compare April 5, 2017 22:22
@0xc0170
Copy link
Contributor

0xc0170 commented Apr 10, 2017

/morph test

@bridadan
Copy link
Contributor

/morph test

@mbed-bot
Copy link

Result: SUCCESS

Your command has finished executing! Here's what you wrote!

/morph test

Output

mbed Build Number: 1866

All builds and test passed!

@sg- sg- merged commit e532e0f into ARMmbed:master Apr 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants