Skip to content

kernel + posix: add k_spin_trylock(), pthread_spin_lock(), etc #59911

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 6 commits into from
Jul 6, 2023

Conversation

cfriedt
Copy link
Member

@cfriedt cfriedt commented Jul 2, 2023

This change adds a new spinlock API, k_spin_trylock(), in order to implement pthread_spin_lock() and friends. Part of the POSIX Roadmap for LTSv3.

Fixes #59910

@zephyrbot zephyrbot added area: POSIX POSIX API Library area: Kernel labels Jul 2, 2023
@zephyrbot zephyrbot requested review from ceolin and peter-mitsis July 2, 2023 18:30
@cfriedt cfriedt added the area: Tests Issues related to a particular existing or missing test label Jul 2, 2023
@cfriedt cfriedt force-pushed the pthread-spinlocks branch from a89bf38 to a4ee073 Compare July 2, 2023 18:43
@cfriedt cfriedt requested review from aescolar and daor-oti as code owners July 2, 2023 18:43
@zephyrbot zephyrbot added area: Portability Standard compliant code, toolchain abstraction area: CMSIS API Layer CMSIS-RTOS API Layer labels Jul 2, 2023
@cfriedt cfriedt force-pushed the pthread-spinlocks branch from a4ee073 to 315ed52 Compare July 2, 2023 18:47
@cfriedt cfriedt added area: Documentation and removed area: CMSIS API Layer CMSIS-RTOS API Layer labels Jul 2, 2023
@cfriedt cfriedt force-pushed the pthread-spinlocks branch from 315ed52 to 9302399 Compare July 2, 2023 19:17
@zephyrbot zephyrbot added the area: CMSIS API Layer CMSIS-RTOS API Layer label Jul 2, 2023
@cfriedt cfriedt removed the area: CMSIS API Layer CMSIS-RTOS API Layer label Jul 3, 2023
@cfriedt cfriedt force-pushed the pthread-spinlocks branch from 2b8bb59 to a17cf28 Compare July 3, 2023 01:53
@zephyrbot zephyrbot added the area: CMSIS API Layer CMSIS-RTOS API Layer label Jul 3, 2023
@cfriedt cfriedt force-pushed the pthread-spinlocks branch 2 times, most recently from b842bb2 to 52234f1 Compare July 3, 2023 11:57
return l - posix_spinlock_pool;
#else
/* Workaround for struct k_spinlock being zero bytes */
__ASSERT_NO_MSG(sizeof(struct k_spinlock))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why runtime assertion? Let's use BUILD_ASSERT.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea

Copy link
Member Author

@cfriedt cfriedt Jul 3, 2023

Choose a reason for hiding this comment

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

@evgeniy-paltsev - Fixed!

@cfriedt cfriedt force-pushed the pthread-spinlocks branch from 52234f1 to 621a587 Compare July 3, 2023 16:34
peter-mitsis
peter-mitsis previously approved these changes Jul 5, 2023
Copy link
Collaborator

@peter-mitsis peter-mitsis left a comment

Choose a reason for hiding this comment

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

Looks good to me.

ycsin
ycsin previously approved these changes Jul 5, 2023
Copy link
Member

@ycsin ycsin left a comment

Choose a reason for hiding this comment

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

re-stamp

andyross
andyross previously approved these changes Jul 5, 2023
@cfriedt cfriedt dismissed stale reviews from andyross, ycsin, and peter-mitsis via 4aaffbc July 5, 2023 21:35
@cfriedt cfriedt force-pushed the pthread-spinlocks branch from 4d15ba6 to 4aaffbc Compare July 5, 2023 21:35
@zephyrbot zephyrbot added the area: Coding Guidelines Coding guidelines and style label Jul 5, 2023
@zephyrbot zephyrbot requested a review from keith-zephyr July 5, 2023 21:35
@cfriedt cfriedt force-pushed the pthread-spinlocks branch from 4aaffbc to f2c40ad Compare July 5, 2023 21:42
@cfriedt
Copy link
Member Author

cfriedt commented Jul 5, 2023

@andyross, @peter-mitsis, @ycsin - please re-stamp.

I added a change to scripts/checkpatch.pl to avoid the USE_NEGATIVE_ERRNO false positive when dealing with .*/lib/posix/.*\.c.

That will let us avoid the need for merge superpowers constantly for lib/posix/, which was annoying.

The `USE_NEGATIVE_ERRNO` rule consistently generates false
positives when working with certain areas of POSIX.

It makes sense to disable this check for the POSIX API
rather than requiring merge superpowers constantly. That
way, we can merge as per usual after sufficient approvals
rather than waiting for someone with merge superpowers to
override / manually merge.

Signed-off-by: Christopher Friedt <[email protected]>
@cfriedt cfriedt force-pushed the pthread-spinlocks branch from f2c40ad to 9d09b4c Compare July 5, 2023 21:52
@xyzzy42
Copy link
Contributor

xyzzy42 commented Jul 5, 2023

There is some opportunity to increase compiler optimization by providing the public pthread methods as inline wrappers that take a pthread_spinlock_t* argument and passes it to an internal function, but first convert the argument to a pthread_spinlock_t or bit.

The check that lock is not NULL can likely be resolved by the compiler at compile time. It's possible to avoid even allocating space for lock and have it live in a register (would need a somewhat limited scope for the lock to be defined over to actually be done). *lock needs to be loaded from RAM on each call, since the compiler can not determine nothing changes it. But if an inline function (or LTO!) is used, the compiler can see that nothing changes the value and avoid the instructions to reload it.

@cfriedt
Copy link
Member Author

cfriedt commented Jul 5, 2023

There is some opportunity to increase compiler optimization by providing the public pthread methods as inline wrappers that take a pthread_spinlock_t* argument and passes it to an internal function, but first convert the argument to a pthread_spinlock_t or bit.

There is always room for optimization but that can be done on an as-needed basis at a later date with evidence / measurements. Additionally, having something that works and meets the spec is more important, and I would avoid inlining anything that isn't specifically mentioned that it could possibly be an inline function or macro.

The check that lock is not NULL can likely be resolved by the compiler at compile time. It's possible to avoid even

Technically, that check isn't even required by the standard and it represents undefined behaviour. I was thinking about making it an __ASSERT_NO_MSG() since that can easily be disabled.

allocating space for lock and have it live in a register (would need a somewhat limited scope for the lock to be defined over to actually be done). *lock needs to be loaded from RAM on each call, since the compiler can not determine nothing changes it. But if an inline function (or LTO!) is used, the compiler can see that nothing changes the value and avoid the instructions to reload it.

Yep - keeping lock in a register would have benefits, but it also isn't clear to me how to return multiple values in registers. Additionally, there is no "invalid lock" value as part of the k_spinlock API. We can leave that to future optimization (ideally before the next release).

Copy link
Collaborator

@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.

Refresh +1

@xyzzy42
Copy link
Contributor

xyzzy42 commented Jul 5, 2023

Technically, that check isn't even required by the standard and it represents undefined behaviour. I was thinking about making it an __ASSERT_NO_MSG() since that can easily be disabled.

The same also for both checks for use of an uninitialized spinlock, undefined behavior in POSIX, but certainly a nice debugging aid. The second check makes all spinlocks contend for access to the single spinlock protecting posix_spinlock_bitarray. I suppose scaling probably isn't much of a concern. The flash sharing caused by having all spinlocks be adjacent in memory will not help scaling either.

@cfriedt cfriedt merged commit 6e27b7d into zephyrproject-rtos:main Jul 6, 2023
@cfriedt cfriedt removed the area: CMSIS API Layer CMSIS-RTOS API Layer label Jul 21, 2023
@cfriedt cfriedt deleted the pthread-spinlocks branch March 27, 2024 00:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Coding Guidelines Coding guidelines and style area: Documentation area: Kernel area: Portability Standard compliant code, toolchain abstraction area: POSIX POSIX API Library area: Tests Issues related to a particular existing or missing test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

posix: pthread: support POSIX spinlocks
7 participants