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: Add mutex wrapper for single thread app #63935

Conversation

nandojve
Copy link
Member

@nandojve nandojve commented Oct 13, 2023

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:

  • serial
  • timers
  • flash driver and layout
  • Non-Volatile Storage NVS
  • pinctrl
  • clocks
  • ring buffers

Prove of Concept:

  • Microcontroller: STM32L010X4
  • Main thread: 512 bytes
  • Transmission buffers: 2 x 128 bytes
  • Serial protocol for communication
Memory region         Used Size  Region Size  %age Used
           FLASH:       14060 B        15 KB     91.53%
             RAM:        1480 B         2 KB     72.27%

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:

west build -b b_l072z_lrwan1 samples/subsys/nvs

Memory region         Used Size  Region Size  %age Used
           FLASH:       27392 B       192 KB     13.93%
             RAM:        4216 B        20 KB     20.59%

@dcpleung
Copy link
Member

Personally, I think you can roll the changes in mutex_st.c into mutex.c as you can basically #ifdef the bodies of those functions, which should be clean enough.

@nandojve nandojve force-pushed the single_thread/add_mutex_wrap branch 2 times, most recently from 6b5f0a3 to 1ad1ae9 Compare October 15, 2023 08:38
Copy link
Member

@cfriedt cfriedt left a 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

include/zephyr/kernel.h Outdated Show resolved Hide resolved
kernel/mutex.c Outdated Show resolved Hide resolved
kernel/mutex.c Outdated Show resolved Hide resolved
@nandojve
Copy link
Member Author

Hi @cfriedt ,

I wonder if this might let us include a number of other test suites that are filtered out with CONFIG_MULTITHREADING

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?

@cfriedt
Copy link
Member

cfriedt commented Oct 15, 2023

@nandojve

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

https://github.com/search?q=repo%3Azephyrproject-rtos%2Fzephyr+multithreading+language%3Ayaml&type=code

@hongshui3000
Copy link
Contributor

hongshui3000 commented Oct 17, 2023

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

1697533739868

@nandojve nandojve force-pushed the single_thread/add_mutex_wrap branch from 64183fc to 3cc31e0 Compare October 17, 2023 10:11
@MaureenHelm
Copy link
Member

@peter-mitsis can you take a look?

@@ -2927,12 +2929,12 @@ struct k_mutex {
* @cond INTERNAL_HIDDEN
*/
#define Z_MUTEX_INITIALIZER(obj) \
{ \
IF_ENABLED(CONFIG_MULTITHREADING, ({ \
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
IF_ENABLED(CONFIG_MULTITHREADING, ({ \
{IF_ENABLED(CONFIG_MULTITHREADING, ( \

Copy link
Member

@cfriedt cfriedt Nov 5, 2023

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done!

include/zephyr/kernel.h Outdated Show resolved Hide resolved
Copy link
Member

@cfriedt cfriedt left a 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.

@peter-mitsis
Copy link
Collaborator

Adding my 2 cents ... I agree with the assessment from @cfriedt .

Copy link
Contributor

@andyross andyross left a 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>
@nandojve nandojve force-pushed the single_thread/add_mutex_wrap branch from 3cc31e0 to d533d25 Compare December 31, 2023 13:58
@zephyrbot zephyrbot requested a review from npitre December 31, 2023 13:58
@nandojve
Copy link
Member Author

nandojve commented Jan 9, 2024

Hi @andyross ,

Can you revisit and let me know if something is missing? It important to us have this on v3.6.

Copy link
Member

@cfriedt cfriedt left a 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.

@nandojve
Copy link
Member Author

Hi @andyross ,

Can you revisit and let me know if something is missing? It important to us have this on v3.6.

ping

@nandojve nandojve added this to the v3.6.0 milestone Feb 1, 2024
@nandojve
Copy link
Member Author

nandojve commented Feb 1, 2024

friendly ping

@npitre
Copy link
Collaborator

npitre commented Feb 1, 2024 via email

@nandojve
Copy link
Member Author

nandojve commented Feb 1, 2024

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.

@npitre
Copy link
Collaborator

npitre commented Feb 1, 2024 via email

Copy link
Member

@nashif nashif left a 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....

@nashif
Copy link
Member

nashif commented Feb 1, 2024

#8393 (comment)
#9808
#27415

This is basically similar to this: #8368

@otavio
Copy link
Contributor

otavio commented Feb 1, 2024

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.

@dcpleung
Copy link
Member

dcpleung commented Feb 1, 2024

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 CONFIG_MULTITHREADING is n). It avoids the headache of having multiple mutex implementations.

@otavio
Copy link
Contributor

otavio commented Feb 1, 2024

@dcpleung, many drivers would need to be changed, while the mutex wrapper allows multiple drivers to work out of the box.

@npitre
Copy link
Collaborator

npitre commented Feb 1, 2024 via email

@dcpleung dcpleung self-requested a review February 2, 2024 00:21
@dcpleung
Copy link
Member

dcpleung commented Feb 2, 2024

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 .config, and that it would not be hiding behind CONFIG_MULTITHREADING. Then you will also need another kconfig to turn OFF k_mutex (or rather have a default enabled kconfig for mutex). Having separate source file for this would work with this scheme. Though, it still conflicts with the idea that we shouldn't be do single threaded version of kernel objects.

@henrikbrixandersen henrikbrixandersen removed this from the v3.6.0 milestone Feb 10, 2024
Copy link

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.

@github-actions github-actions bot added the Stale label Apr 11, 2024
@nandojve nandojve removed the Stale label Apr 11, 2024
Copy link

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.

@github-actions github-actions bot added the Stale label Jun 11, 2024
@nandojve nandojve removed the Stale label Jun 11, 2024
Copy link

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.

@github-actions github-actions bot added the Stale label Aug 11, 2024
@cfriedt cfriedt removed the Stale label Aug 11, 2024
Copy link

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.

@github-actions github-actions bot added the Stale label Oct 11, 2024
@github-actions github-actions bot closed this Oct 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.