Skip to content
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

kernel: queue, fifo: Add cancel_wait operation. #26

Merged
merged 1 commit into from
May 10, 2017

Conversation

pfalcon
Copy link
Contributor

@pfalcon pfalcon commented May 1, 2017

Currently, a queue/fifo getter chooses how long to wait for an
element. But there are scenarios when putter would know better,
there should be a way to expire getter's timeout to make it run
again. k_queue_cancel_wait() and k_fifo_cancel_wait() functions
do just that. They cause corresponding *_get() functions to return
with NULL value, as if timeout expired on getter's side (even
K_FOREVER).

This can be used to signal out of band conditions from putter to
getter, e.g. end of processing, error, configuration change, etc.
A specific event would be communicated to getter by other means
(e.g. using existing shared context structures).

Without this call, achieving the same effect would require e.g.
calling k_fifo_put() with a pointer to a special sentinal memory
structure - such structure would need to be allocated somewhere
and somehow, and getter would need to recognize it from a normal
data item. Having cancel_wait() functions offers an elegant
alternative. From this perspective, these calls can be seen as
an equivalent to e.g. k_fifo_put(fifo, NULL), except that such
call won't work in practice.

Change-Id: I47b7f690dc325a80943082bcf5345c41649e7024
Signed-off-by: Paul Sokolovsky paul.sokolovsky@linaro.org


This change is Reviewable

@pfalcon
Copy link
Contributor Author

pfalcon commented May 1, 2017

@Vudentz
Copy link
Contributor

Vudentz commented May 1, 2017

I guess most of the waiters don't really expect a NULL pointer on wakeup, and in most cases it is just a nop, so I would be very careful introducing something like this to existing code, perhaps we should only allow this just to a version of k_*_get that allows canceling? Also having tests for this new API is a must have imo.

@nashif nashif self-assigned this May 1, 2017
@pfalcon
Copy link
Contributor Author

pfalcon commented May 1, 2017

I guess most of the waiters don't really expect a NULL pointer on wakeup,

What do you mean? From the doc on k_fifo_get():

 * @return Address of the data item if successful; NULL if returned
 * without waiting, or waiting period timed out.

and in most cases it is just a nop, so I would be very careful introducing something like this to existing code

Sorry, this doesn't introduce anything to the existing code. This introduces a new API for the code which needs it, it doesn't affect existing code in any way.

Also having tests for this new API is a must have imo.

That's exactly the reason why they are included.

@pfalcon
Copy link
Contributor Author

pfalcon commented May 2, 2017

@andrewboie

@pfalcon
Copy link
Contributor Author

pfalcon commented May 4, 2017

@dbkinder : Can you please check docstrings here? Don't hesitate to approve this PR if they're ok ;-).

@andyross
Copy link
Contributor

andyross commented May 4, 2017

Can't see anything wrong with the implementation.

That said: is there a real world use case for this? It seems kind of weird to me: sort of a bastard child of a semaphore and a condition variable that is done in the context of a "queue/fifo/lifo" which is a somewhat higher level synchronization abstraction.

Maybe a simpler solution (or if not simpler, at least one which didn't invent a new synchronization technique) would be to add k_queue into the k_poll implementation so applications can wait on a fifo/lifo and some other object?

@pfalcon
Copy link
Contributor Author

pfalcon commented May 4, 2017

@andyross : Thanks for the review.

That said: is there a real world use case for this?

Yes, this comes from my work on implementing BSD Sockets API. It's out of tree so far: https://github.com/pfalcon/micropython/blob/zephyr-socket2/zephyr/modusocket.c#L178 , but would go in-tree. It just won't be ready 1.8, but I'm trying to submit any sufficiently independent parts ahead of time, to avoid gigantic patches later. This functionality is IMHO pretty independent and makes queue/fifo more complete. For example, @jhedberg in IRC discussion mentioned that in BT subsystem has a similar issue and they created sentinel object to overcome it. Perhaps, the sooner this patch gets into tree, the more people will leverage it.

one which didn't invent a new synchronization technique

Well, it's not really a new synchronization technique, arguably, ability to cancel a pending wait should be a part of the API for waiting synchronization primitives, and Zephyr lacks it.

Maybe a simpler solution (or if not simpler, at least one which didn't invent a new synchronization technique) would be to add k_queue into the k_poll implementation so applications can wait on a fifo/lifo and some other object?

So, I'm working on BSD Sockets implementation which already adds quite a bit of overhead. But beyond overhead which is unavoidably required (like need to maintain a fifo per network context), I wouldn't like to introduce any other overhead. And unfortunately, any object which can be k_poll'ed has quite high memory overhead (in my valuation, an extra machine word is "high overhead", anything beyond that is "quite high overhead", IIRC any synchronization primitive in Zephyr adds at least 2 machine words).

Hopefully that explains it.

Currently, a queue/fifo getter chooses how long to wait for an
element. But there are scenarios when putter would know better,
there should be a way to expire getter's timeout to make it run
again. k_queue_cancel_wait() and k_fifo_cancel_wait() functions
do just that. They cause corresponding *_get() functions to return
with NULL value, as if timeout expired on getter's side (even
K_FOREVER).

This can be used to signal out of band conditions from putter to
getter, e.g. end of processing, error, configuration change, etc.
A specific event would be communicated to getter by other means
(e.g. using existing shared context structures).

Without this call, achieving the same effect would require e.g.
calling k_fifo_put() with a pointer to a special sentinal memory
structure - such structure would need to be allocated somewhere
and somehow, and getter would need to recognize it from a normal
data item. Having cancel_wait() functions offers an elegant
alternative. From this perspective, these calls can be seen as
an equivalent to e.g. k_fifo_put(fifo, NULL), except that such
call won't work in practice.

Change-Id: I47b7f690dc325a80943082bcf5345c41649e7024
Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
@nashif nashif merged commit 3f50707 into zephyrproject-rtos:master May 10, 2017
nagineni pushed a commit to nagineni/zephyr that referenced this pull request Nov 20, 2017
[BLE] Set up BLE advertising based on values from JavaScript
frasa pushed a commit to blik-GmbH/zephyr that referenced this pull request Mar 25, 2019
* Changed branch-off point for gitlinting from `dev` to `origin/dev`
* Since GitLab uses the git checkout policy for the CI runners the
entire Zephyr history was checked, whereas now it is indeed only the new
feature branch which gets checked back to its branch-off point from the
dev branch.

Closes zephyrproject-rtos#26

Signed-Off-By: Alexander Preißner <alexander.preissner@blik.io>
frasa added a commit to blik-GmbH/zephyr that referenced this pull request Mar 25, 2019
fix: CI: correct branch-off point for gitlint

Closes zephyrproject-rtos#26

See merge request blik/embedded/zephyr!32
ulfalizer pushed a commit to ulfalizer/zephyr that referenced this pull request May 13, 2019
Replace with Error(msg, "error")

Typo introduced in previous commit / PR zephyrproject-rtos#26. Fixes the following
console output:

  WARNING : Skipped Gitlint failed: ...

I don't know the impact on Github however this just restores the
previous behavior.

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
ulfalizer pushed a commit to ulfalizer/zephyr that referenced this pull request Oct 23, 2019
Replace with Error(msg, "error")

Typo introduced in previous commit / PR zephyrproject-rtos#26. Fixes the following
console output:

  WARNING : Skipped Gitlint failed: ...

I don't know the impact on Github however this just restores the
previous behavior.

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants