posix: Fix pthread_once has incorrect behavior

As described in
https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_once.html.
The behavior of pthread_once() is undefined if once_control has
automatic storage duration or is not initialized by PTHREAD_ONCE_INIT

However, in Zephyr, the implementation is incorrect. If the init value
is PTHREAD_ONCE_INIT, the program will never run the init_func.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
This commit is contained in:
Jaxson Han 2022-03-11 11:33:39 +08:00 committed by Marti Bolivar
commit 0e1ff84fe7
3 changed files with 5 additions and 4 deletions

View file

@ -334,13 +334,13 @@ int pthread_once(pthread_once_t *once, void (*init_func)(void))
{ {
pthread_mutex_lock(&pthread_key_lock); pthread_mutex_lock(&pthread_key_lock);
if (*once == PTHREAD_ONCE_INIT) { if (*once != PTHREAD_ONCE_INIT) {
pthread_mutex_unlock(&pthread_key_lock); pthread_mutex_unlock(&pthread_key_lock);
return 0; return 0;
} }
init_func(); init_func();
*once = PTHREAD_ONCE_INIT; *once = 0;
pthread_mutex_unlock(&pthread_key_lock); pthread_mutex_unlock(&pthread_key_lock);

View file

@ -410,7 +410,7 @@ void test_posix_pthread_error_condition(void)
void *stackaddr; void *stackaddr;
size_t stacksize; size_t stacksize;
int policy, detach; int policy, detach;
static pthread_once_t key = 1; static pthread_once_t key;
/* TESTPOINT: invoke pthread APIs with NULL */ /* TESTPOINT: invoke pthread APIs with NULL */
zassert_equal(pthread_attr_destroy(NULL), EINVAL, zassert_equal(pthread_attr_destroy(NULL), EINVAL,

View file

@ -17,7 +17,8 @@
K_THREAD_STACK_ARRAY_DEFINE(stackp, N_THR, STACKSZ); K_THREAD_STACK_ARRAY_DEFINE(stackp, N_THR, STACKSZ);
pthread_key_t key, keys[N_KEY]; pthread_key_t key, keys[N_KEY];
static pthread_once_t key_once, keys_once; static pthread_once_t key_once = PTHREAD_ONCE_INIT;
static pthread_once_t keys_once = PTHREAD_ONCE_INIT;
void *thread_top(void *p1) void *thread_top(void *p1)
{ {