-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Optimize mutex atomic fast path #16030
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
xiaoxiang781216
merged 2 commits into
apache:master
from
tiiuae:optimze_mutex_atomic_fast_path
Apr 1, 2025
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
why not remove nxsem_wati and replace line 86 with nxsem_wait_impl directly
Uh oh!
There was an error while loading. Please reload this page.
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.
That was my original idea. However:
It is better to have the functions contained in single compilation unit in libc (in memory protected builds) and in kernel. This is better for code size (and cache locality)
Uh oh!
There was an error while loading. Please reload this page.
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.
I don't see any reason that the code size will increase significantly. nxsem_wait is identical to nxsem_trywait_slow except DEBUGASSERT which is no-op in release build.
DEBUGASSERT can be called in userspace too, why do you need add
__KERNEL__? sem_xxx could check sem != NULL before invoking nxsem_xxx, nxsem_xxx could DEBUGASSERT before invoking nsem_xxx_slow.Since nxsem_xxx_slow become the syscall function but nxsem_xxx as the normal function, you can implment nxsem_xxx as non inline function and put them into libs/libc/semaphore/ and remove the version under sched/semaphore/ directly.
if you really want you can change nxsem_post_impl to static inline function and move it into libs/libc/semaphore/sem_post.c which alredy contain both sem_post and nxsem_post.
and move these prototype into include/nuttx/semaphore.h:
and remove include/nuttx/sem_fast.h.
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.
I don't understand what you are talking about. If you inline sem_wait, sem_trywait and sem_post, obviously the code size will increase since all that code will be included in every compilation unit where these funcitions are used (kernel drivers, kernel nxmutex, libc nxmutex, libc sem.... In addition that will be a mess because of atomic.h including in all of those places.
Yes, but why? You still need two c-files, so why not keep just the common code in the current "inline" and leave the libc specifics in libc c-file and kernel specifics in kernel c-file.
Of course I can include the _slow prototypes into include/nuttx/semaphore.h. But why? These are now not supposed to be called from anywhere else than the corresponding inline functions. And those inline functions are put into an own header to avoid nasty atomics dependencies. It is easier to include them only in those C files where they are actually used.
And you can't put the code only into libc. That is the whole point why I made them originally macros and later inline functions. You need them both in kernel and in libc. The inline functions are made only for the purpose that the code doesn't need to be duplicated, but it can be included in the corresponding C files, in kernel and in libc.
In protected builds, you can't call libc function from kernel or kernel function from libc. You must have nxsem_wait, nxsem_trywait and nxsem_post in BOTH libc AND kernel.
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.
You don't need two c-files. nxsem_xxx is a normal function now, but call nxsem_xxx_slow kernel function, so you can put nxsem_xxx and sem_xxx into the same libc source file, and change nxsem_xxx_impl to static function, or let's sem_xxx call nxsem_xxx directly and let compiler optimize them.
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.
but sem_xxx need modify errno from POSIX.
inline the implementation could avoid the duplication.
Uh oh!
There was an error while loading. Please reload this page.
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.
Yes, obviously. But in libc there is pthread_mutex (maybe others?) that need the fast path as well. So we need a function that implements the fast path without touching errno / cancel points.
Yes this is one option, the inline code would then be accessed from both user and kernel ?
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.
I'll change to this, I like it better than having nxsem* in libc as well. A bit of a hassle since we need to change all calls of nxsem within libc.
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.
@pussuw: there are other nxsem functions in libc: nxsem_set_protocol, nxsem_getprioceiling, nxsem_setprioceiling, nxsem_set_protocol.
These are all used both in kernel and in libc. I am not going to re-work this all. And nxsem is not the only interface which is implemented like this.
I believe it is cleaner to change our interpretation of nx* naming that it means "internal to nuttx" instead of "internal to kernel", and keep the current implementation.
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.
Well, it's not only about naming, we also need to link libc into the kernel, but it seems we need to do it regardless of this change.