-
Notifications
You must be signed in to change notification settings - Fork 7.4k
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
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
d10d246
kernel: spinlock: add k_spin_trylock()
cfriedt 089f49a
tests: kernel: spinlock: add test for k_spin_trylock()
cfriedt cc1e7fd
posix: pthread: implement pthread spinlocks
cfriedt 0d6d90c
tests: posix: common: add pthread spinlock tests
cfriedt 4d15ba6
doc: services: portability: posix: support for POSIX_SPIN_LOCKS
cfriedt 9d09b4c
checkpatch: exclude lib/posix/*.c from negative errno rule
cfriedt 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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
/* | ||
* Copyright (c) 2023, Meta | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "posix_internal.h" | ||
|
||
#include <zephyr/init.h> | ||
#include <zephyr/kernel.h> | ||
#include <zephyr/posix/pthread.h> | ||
#include <zephyr/sys/bitarray.h> | ||
|
||
union _spinlock_storage { | ||
struct k_spinlock lock; | ||
uint8_t byte; | ||
}; | ||
#if !defined(CONFIG_SMP) && !defined(CONFIG_SPIN_VALIDATE) | ||
BUILD_ASSERT(sizeof(struct k_spinlock) == 0, | ||
"please remove the _spinlock_storage workaround if, at some point, k_spinlock is no " | ||
"longer zero bytes when CONFIG_SMP=n && CONFIG_SPIN_VALIDATE=n"); | ||
#endif | ||
|
||
static union _spinlock_storage posix_spinlock_pool[CONFIG_MAX_PTHREAD_SPINLOCK_COUNT]; | ||
static k_spinlock_key_t posix_spinlock_key[CONFIG_MAX_PTHREAD_SPINLOCK_COUNT]; | ||
SYS_BITARRAY_DEFINE_STATIC(posix_spinlock_bitarray, CONFIG_MAX_PTHREAD_SPINLOCK_COUNT); | ||
|
||
/* | ||
* We reserve the MSB to mark a pthread_spinlock_t as initialized (from the | ||
* perspective of the application). With a linear space, this means that | ||
* the theoretical pthread_spinlock_t range is [0,2147483647]. | ||
*/ | ||
BUILD_ASSERT(CONFIG_MAX_PTHREAD_SPINLOCK_COUNT < PTHREAD_OBJ_MASK_INIT, | ||
"CONFIG_MAX_PTHREAD_SPINLOCK_COUNT is too high"); | ||
|
||
static inline size_t posix_spinlock_to_offset(struct k_spinlock *l) | ||
{ | ||
return (union _spinlock_storage *)l - posix_spinlock_pool; | ||
} | ||
|
||
static inline size_t to_posix_spinlock_idx(pthread_spinlock_t lock) | ||
{ | ||
return mark_pthread_obj_uninitialized(lock); | ||
} | ||
|
||
static struct k_spinlock *get_posix_spinlock(pthread_spinlock_t *lock) | ||
{ | ||
size_t bit; | ||
int actually_initialized; | ||
|
||
if (lock == NULL) { | ||
return NULL; | ||
} | ||
|
||
/* if the provided spinlock does not claim to be initialized, its invalid */ | ||
bit = to_posix_spinlock_idx(*lock); | ||
if (!is_pthread_obj_initialized(*lock)) { | ||
return NULL; | ||
} | ||
|
||
/* Mask off the MSB to get the actual bit index */ | ||
if (sys_bitarray_test_bit(&posix_spinlock_bitarray, bit, &actually_initialized) < 0) { | ||
return NULL; | ||
} | ||
|
||
if (actually_initialized == 0) { | ||
/* The spinlock claims to be initialized but is actually not */ | ||
return NULL; | ||
} | ||
|
||
return (struct k_spinlock *)&posix_spinlock_pool[bit]; | ||
} | ||
|
||
int pthread_spin_init(pthread_spinlock_t *lock, int pshared) | ||
{ | ||
int ret; | ||
size_t bit; | ||
|
||
if (lock == NULL || | ||
!(pshared == PTHREAD_PROCESS_PRIVATE || pshared == PTHREAD_PROCESS_SHARED)) { | ||
/* not specified as part of POSIX but this is the Linux behavior */ | ||
return EINVAL; | ||
} | ||
|
||
ret = sys_bitarray_alloc(&posix_spinlock_bitarray, 1, &bit); | ||
if (ret < 0) { | ||
return ENOMEM; | ||
} | ||
|
||
*lock = mark_pthread_obj_initialized(bit); | ||
|
||
return 0; | ||
} | ||
|
||
int pthread_spin_destroy(pthread_spinlock_t *lock) | ||
{ | ||
int err; | ||
size_t bit; | ||
struct k_spinlock *l; | ||
|
||
l = get_posix_spinlock(lock); | ||
if (l == NULL) { | ||
/* not specified as part of POSIX but this is the Linux behavior */ | ||
return EINVAL; | ||
} | ||
|
||
bit = posix_spinlock_to_offset(l); | ||
err = sys_bitarray_free(&posix_spinlock_bitarray, 1, bit); | ||
__ASSERT_NO_MSG(err == 0); | ||
|
||
return 0; | ||
} | ||
|
||
int pthread_spin_lock(pthread_spinlock_t *lock) | ||
{ | ||
size_t bit; | ||
struct k_spinlock *l; | ||
|
||
l = get_posix_spinlock(lock); | ||
if (l == NULL) { | ||
/* not specified as part of POSIX but this is the Linux behavior */ | ||
return EINVAL; | ||
} | ||
|
||
bit = posix_spinlock_to_offset(l); | ||
posix_spinlock_key[bit] = k_spin_lock(l); | ||
|
||
return 0; | ||
} | ||
|
||
int pthread_spin_trylock(pthread_spinlock_t *lock) | ||
{ | ||
size_t bit; | ||
struct k_spinlock *l; | ||
|
||
l = get_posix_spinlock(lock); | ||
if (l == NULL) { | ||
/* not specified as part of POSIX but this is the Linux behavior */ | ||
return EINVAL; | ||
} | ||
|
||
bit = posix_spinlock_to_offset(l); | ||
return k_spin_trylock(l, &posix_spinlock_key[bit]); | ||
} | ||
|
||
int pthread_spin_unlock(pthread_spinlock_t *lock) | ||
{ | ||
size_t bit; | ||
struct k_spinlock *l; | ||
|
||
l = get_posix_spinlock(lock); | ||
if (l == NULL) { | ||
/* not specified as part of POSIX but this is the Linux behavior */ | ||
return EINVAL; | ||
} | ||
|
||
bit = posix_spinlock_to_offset(l); | ||
k_spin_unlock(l, posix_spinlock_key[bit]); | ||
|
||
return 0; | ||
} |
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.
Uh oh!
There was an error while loading. Please reload this page.