-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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: Add mutex wrapper for single thread app #63935
kernel: Add mutex wrapper for single thread app #63935
Conversation
Personally, I think you can roll the changes in |
6b5f0a3
to
1ad1ae9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of cosmetic suggestions at the moment.
I wonder if this might let us include a number of other test suites that are filtered out with CONFIG_MULTITHREADING
Hi @cfriedt ,
What I have been testing locally was to enable NVS subsystem, which only depends on this sync primitive. I would like know if you are suggesting that we think about a new config that enables this subsystem with the single thread option or your suggestion goes in the direction of more specific tests? |
I don't have any tests in mind yet but a quick search reveals some possibilities |
1ad1ae9
to
64183fc
Compare
I think it would be better to change the subsystem to support single-threaded applications rather than changing the mutex. Obviously mutex is generally used in multi-threaded applications. After the change, it can also be used in a single thread, but it has no effect. This is very strange and illogical software behavior Note that the entire change seems to be changing the behavior of the previous documentation convention |
64183fc
to
3cc31e0
Compare
@peter-mitsis can you take a look? |
include/zephyr/kernel.h
Outdated
@@ -2927,12 +2929,12 @@ struct k_mutex { | |||
* @cond INTERNAL_HIDDEN | |||
*/ | |||
#define Z_MUTEX_INITIALIZER(obj) \ | |||
{ \ | |||
IF_ENABLED(CONFIG_MULTITHREADING, ({ \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IF_ENABLED(CONFIG_MULTITHREADING, ({ \ | |
{IF_ENABLED(CONFIG_MULTITHREADING, ( \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might want to use COND_CODE_1()
and set the "else" clause to (0)
so that the initializer becomes {0}
, which is possibly more pedantically-correct or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 minor changes to get around the 1 error in CI.
Otherwise, just a rebase to resolve conflicts and LGTM.
Adding my 2 cents ... I agree with the assessment from @cfriedt . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style: this is a lot of #if'ery to add to a (somewhat fragile!) C file just to make it act like a noop.
Can't you do this at a header level somewhere just by changing the struct definition and making the calls empty inlines?
There are subsystems in Zephyr that require synchronization primitives because the default behavior of Zephyr is to build multi-thread applications. This add very small change in the kernel related to mutexes that affects only single thread build. The change define the k_mutex as an empty struct and the lock/unlock functions are bypassed. This allows few subsystem be used in single thread application without touch the subsystem code. The change keeps Zephyr flexible and help to stay with very low code and sram profile for the very constrained applications that still require some functionality like Non-Volatile Storage. Signed-off-by: Gerson Fernando Budke <gerson.budke@ossystems.com.br>
3cc31e0
to
d533d25
Compare
Hi @andyross , Can you revisit and let me know if something is missing? It important to us have this on v3.6. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still looks ok to me.
ping |
friendly ping |
My previous comment still stands. If this were under my responsibility,
I'd ask you to create a mutex_singlethread.c alternative to put dummies
in there and leave mutex.c alone.
|
Hi @npitre , This was my initial proposal. Originally posted by @dcpleung in #63935 (comment) So, there are many tastes and it has been difficult to adjust contradictory expectations. |
Well... I usually agree with @dcpleung but not in this particular case.
Mutexes may have their share of implementation subtleties, and e.g.
@andyross has a "zync" implementation replacement on the backburner. No
need to complicate things with a dummy "single-thread" variant woven
into the real variant making maintenance for both variants more
difficult. It is not like if any potential addition/improvement to the
real mutex would also benefit the dummy one either.
For those reasons I think it is best to keep a special, and not quite
mutex-like behaving version only for the purpose of satisfying the build
in a single-threaded environment separate. Who knows what condition you
might encounter, like actually having to wait on an IRQ to fire and
unlock a mutex you're waiting for. That might happen even in a
single-thread scenario, in which case your dummy mutex won't be as dummy
anymore (i.e. k_mutex_lock() would have to spin calling the idle thread
function while the coundt != 0 and have k_mutex_unlock() simply
decrement the count from the ISR). Do you see yourself trying to fit
that behavior in mutex.c without turning it into a mess?
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The project, long time ago, decided not do any of that and to refrain from changing kernel premitives to support single thread and the documentation does reflect that clearly. I will find the relevant history and the decision made, until then....
This is basically similar to this: #8368 |
The support for a single thread is currently available, but it is not yet complete. This feature allows drivers to function in applications that require a single thread, and depending on the driver used, it can consume a significant amount of RAM and ROM. In some cases, like ours, utilizing Zephyr with the single thread option is the only viable solution. We used this feature in our project to avoid using multiple RTOS in the same project, which helped us share code and knowledge more efficiently. |
If it is for drivers, wouldn't it be better to amend the drivers for single thread operation? (e.g. by not using mutex when |
@dcpleung, many drivers would need to be changed, while the mutex wrapper allows multiple drivers to work out of the box. |
Such wrappers have to be discrete, unobstrusive, isolated and ignorable
by those who don't care for such contraptions. Hence the separate file.
Do you still have that version in a separate file? I'd like to see it.
I'm pretty sure mixing this in mutex.c will simply raise objections.
|
Thinking about it more... maybe it would be better to explicitly have a kconfig to enable such a feature. So that it would be obvious when looking at |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
There are subsystems in Zephyr that require synchronization primitives because the default behavior of Zephyr is to build multi-thread applications. This add very small change in the kernel related to mutexes that affects only single thread build.
It add a new file only to wrap the API.The change define the k_mutex as an empty struct and the lock/unlock functions are bypassed. This allows few subsystem be used in single thread application without touch the subsystem code.The change keeps Zephyr flexible and help to stay with very low code and sram profile for the very constrained applications that still require some functionality like Non-Volatile Storage.
With this change is still possible to build a single thread application that uses:
Prove of Concept:
The proposal start to make sense when the solution is compared with the samples/subsys/nvs in their default configuration using a define from the same family: