diff --git a/sys/posix/pthread/include/pthread_once.h b/sys/posix/pthread/include/pthread_once.h index 6c01a4a1759d..2a10358497d1 100644 --- a/sys/posix/pthread/include/pthread_once.h +++ b/sys/posix/pthread/include/pthread_once.h @@ -23,15 +23,21 @@ extern "C" { /** * @brief Datatype to supply to pthread_once(). + * @details This data type must be compatible with the one defined + * in newlib's `include/sys/_pthreadtypes.h`. */ -typedef volatile int pthread_once_t; +typedef struct { + int is_initialized; /**< initialized */ + int init_executed; /**< init function executed */ +} pthread_once_t; /** * @def PTHREAD_ONCE_INIT * @brief Initialization for pthread_once_t. - * @details A zeroed out pthread_once_t is initialized. + * @details pthread_once_t variables are declared as initialized, but + * the init function is not yet executed. */ -#define PTHREAD_ONCE_INIT 0 +#define PTHREAD_ONCE_INIT { 1, 0 } /** * @brief Helper function that ensures that `init_routine` is called at once. diff --git a/sys/posix/pthread/pthread_once.c b/sys/posix/pthread/pthread_once.c index 59bc2d0e7f66..c6ac4dc196fe 100644 --- a/sys/posix/pthread/pthread_once.c +++ b/sys/posix/pthread/pthread_once.c @@ -22,11 +22,11 @@ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { - if (*once_control == PTHREAD_ONCE_INIT) { + if (!once_control->init_executed) { init_routine(); } - *once_control = PTHREAD_ONCE_INIT + 1; + once_control->init_executed = 1; return 0; }