diff --git a/include/zephyr/posix/posix_sched.h b/include/zephyr/posix/posix_sched.h index b36c238a143..4552658f366 100644 --- a/include/zephyr/posix/posix_sched.h +++ b/include/zephyr/posix/posix_sched.h @@ -16,9 +16,11 @@ extern "C" { /* Priority based preemptive scheduling policy */ #define SCHED_RR 2 +#if defined(CONFIG_MINIMAL_LIBC) || defined(CONFIG_PICOLIBC) struct sched_param { int sched_priority; }; +#endif /** * @brief Yield the processor diff --git a/include/zephyr/posix/posix_types.h b/include/zephyr/posix/posix_types.h index ad4a738bf90..c5f33b520d8 100644 --- a/include/zephyr/posix/posix_types.h +++ b/include/zephyr/posix/posix_types.h @@ -11,6 +11,10 @@ #include #endif +#ifdef CONFIG_NEWLIB_LIBC +#include +#endif + #include #ifdef __cplusplus @@ -33,7 +37,7 @@ typedef unsigned long timer_t; #ifdef CONFIG_PTHREAD_IPC /* Thread attributes */ -typedef struct pthread_attr { +struct pthread_attr { int priority; void *stack; uint32_t stacksize; @@ -42,7 +46,11 @@ typedef struct pthread_attr { uint32_t schedpolicy; int32_t detachstate; uint32_t initialized; -} pthread_attr_t; +}; +#if defined(CONFIG_MINIMAL_LIBC) || defined(CONFIG_PICOLIBC) +typedef struct pthread_attr pthread_attr_t; +#endif +BUILD_ASSERT(sizeof(pthread_attr_t) >= sizeof(struct pthread_attr)); typedef uint32_t pthread_t; @@ -52,15 +60,24 @@ typedef struct k_sem sem_t; /* Mutex */ typedef uint32_t pthread_mutex_t; -typedef struct pthread_mutexattr { +struct pthread_mutexattr { int type; -} pthread_mutexattr_t; +}; +#if defined(CONFIG_MINIMAL_LIBC) || defined(CONFIG_PICOLIBC) +typedef struct pthread_mutexattr pthread_mutexattr_t; +#endif +BUILD_ASSERT(sizeof(pthread_mutexattr_t) >= sizeof(struct pthread_mutexattr)); /* Condition variables */ typedef uint32_t pthread_cond_t; -typedef struct pthread_condattr { -} pthread_condattr_t; +struct pthread_condattr { +}; + +#if defined(CONFIG_MINIMAL_LIBC) || defined(CONFIG_PICOLIBC) +typedef struct pthread_condattr pthread_condattr_t; +#endif +BUILD_ASSERT(sizeof(pthread_condattr_t) >= sizeof(struct pthread_condattr)); /* Barrier */ typedef struct pthread_barrier { diff --git a/include/zephyr/posix/pthread.h b/include/zephyr/posix/pthread.h index 6797442eaef..07958e57f80 100644 --- a/include/zephyr/posix/pthread.h +++ b/include/zephyr/posix/pthread.h @@ -31,7 +31,10 @@ extern "C" { #define PTHREAD_CANCEL_DISABLE BIT(_PTHREAD_CANCEL_POS) /* Passed to pthread_once */ -#define PTHREAD_ONCE_INIT 1 +#define PTHREAD_ONCE_INIT \ + { \ + 1, 0 \ + } /* The minimum allowable stack size */ #define PTHREAD_STACK_MIN Z_KERNEL_STACK_SIZE_ADJUST(0) diff --git a/include/zephyr/posix/pthread_key.h b/include/zephyr/posix/pthread_key.h index a572a045a0d..33228357a1c 100644 --- a/include/zephyr/posix/pthread_key.h +++ b/include/zephyr/posix/pthread_key.h @@ -15,7 +15,12 @@ extern "C" { #endif -typedef uint32_t pthread_once_t; +#if defined(CONFIG_MINIMAL_LIBC) || defined(CONFIG_PICOLIBC) +typedef struct { + int is_initialized; + int init_executed; +} pthread_once_t; +#endif /* pthread_key */ typedef uint32_t pthread_key_t; diff --git a/lib/posix/CMakeLists.txt b/lib/posix/CMakeLists.txt index ac4e5527a60..1e7638ccdb2 100644 --- a/lib/posix/CMakeLists.txt +++ b/lib/posix/CMakeLists.txt @@ -7,6 +7,14 @@ if(CONFIG_POSIX_API) target_include_directories(posix_subsys INTERFACE ${ZEPHYR_BASE}/include/zephyr/posix) endif() +if(CONFIG_POSIX_API OR CONFIG_PTHREAD_IPC OR CONFIG_POSIX_CLOCK OR + CONFIG_POSIX_MQUEUE OR CONFIG_POSIX_FS OR CONFIG_EVENTFD OR CONFIG_GETOPT) + # This is a temporary workaround so that Newlib declares the appropriate + # types for us. POSIX features to be formalized as part of #51211 + zephyr_compile_options($<$:-D_POSIX_THREADS>) + zephyr_compile_options($<$:-D_POSIX_THREADS>) +endif() + zephyr_library() zephyr_library_sources_ifdef(CONFIG_POSIX_API perror.c) zephyr_library_sources_ifdef(CONFIG_PTHREAD_IPC pthread_common.c) diff --git a/lib/posix/pthread.c b/lib/posix/pthread.c index 11d3f3d8fad..d561bd49e8d 100644 --- a/lib/posix/pthread.c +++ b/lib/posix/pthread.c @@ -22,7 +22,7 @@ K_MUTEX_DEFINE(pthread_once_lock); -static const pthread_attr_t init_pthread_attrs = { +static const struct pthread_attr init_pthread_attrs = { .priority = LOWEST_POSIX_THREAD_PRIORITY, .stack = NULL, .stacksize = 0, @@ -100,9 +100,9 @@ static int32_t posix_to_zephyr_priority(uint32_t priority, int policy) * * See IEEE 1003.1 */ -int pthread_attr_setschedparam(pthread_attr_t *attr, - const struct sched_param *schedparam) +int pthread_attr_setschedparam(pthread_attr_t *_attr, const struct sched_param *schedparam) { + struct pthread_attr *attr = (struct pthread_attr *)_attr; int priority = schedparam->sched_priority; if ((attr == NULL) || (attr->initialized == 0U) || @@ -119,9 +119,10 @@ int pthread_attr_setschedparam(pthread_attr_t *attr, * * See IEEE 1003.1 */ -int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, - size_t stacksize) +int pthread_attr_setstack(pthread_attr_t *_attr, void *stackaddr, size_t stacksize) { + struct pthread_attr *attr = (struct pthread_attr *)_attr; + if (stackaddr == NULL) { return EACCES; } @@ -147,7 +148,7 @@ static void zephyr_thread_wrapper(void *arg1, void *arg2, void *arg3) * * See IEEE 1003.1 */ -int pthread_create(pthread_t *newthread, const pthread_attr_t *attr, +int pthread_create(pthread_t *newthread, const pthread_attr_t *_attr, void *(*threadroutine)(void *), void *arg) { int rv; @@ -157,6 +158,7 @@ int pthread_create(pthread_t *newthread, const pthread_attr_t *attr, k_spinlock_key_t cancel_key; pthread_condattr_t cond_attr; struct posix_thread *thread; + const struct pthread_attr *attr = (const struct pthread_attr *)_attr; /* * FIXME: Pthread attribute must be non-null and it provides stack @@ -355,9 +357,9 @@ int pthread_once(pthread_once_t *once, void (*init_func)(void)) { k_mutex_lock(&pthread_once_lock, K_FOREVER); - if (*once == PTHREAD_ONCE_INIT) { + if (once->is_initialized != 0 && once->init_executed == 0) { init_func(); - *once = 0; + once->init_executed = 1; } k_mutex_unlock(&pthread_once_lock); @@ -502,8 +504,10 @@ int pthread_detach(pthread_t thread) * * See IEEE 1003.1 */ -int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) +int pthread_attr_getdetachstate(const pthread_attr_t *_attr, int *detachstate) { + const struct pthread_attr *attr = (const struct pthread_attr *)_attr; + if ((attr == NULL) || (attr->initialized == 0U)) { return EINVAL; } @@ -517,8 +521,10 @@ int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) * * See IEEE 1003.1 */ -int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) +int pthread_attr_setdetachstate(pthread_attr_t *_attr, int detachstate) { + struct pthread_attr *attr = (struct pthread_attr *)_attr; + if ((attr == NULL) || (attr->initialized == 0U) || (detachstate != PTHREAD_CREATE_DETACHED && detachstate != PTHREAD_CREATE_JOINABLE)) { @@ -535,8 +541,10 @@ int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) * * See IEEE 1003.1 */ -int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) +int pthread_attr_getschedpolicy(const pthread_attr_t *_attr, int *policy) { + const struct pthread_attr *attr = (const struct pthread_attr *)_attr; + if ((attr == NULL) || (attr->initialized == 0U)) { return EINVAL; } @@ -551,8 +559,10 @@ int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) * * See IEEE 1003.1 */ -int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) +int pthread_attr_setschedpolicy(pthread_attr_t *_attr, int policy) { + struct pthread_attr *attr = (struct pthread_attr *)_attr; + if ((attr == NULL) || (attr->initialized == 0U) || (policy != SCHED_RR && policy != SCHED_FIFO)) { return EINVAL; @@ -567,8 +577,10 @@ int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) * * See IEEE 1003.1 */ -int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) +int pthread_attr_getstacksize(const pthread_attr_t *_attr, size_t *stacksize) { + const struct pthread_attr *attr = (const struct pthread_attr *)_attr; + if ((attr == NULL) || (attr->initialized == 0U)) { return EINVAL; } @@ -583,8 +595,10 @@ int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) * * See IEEE 1003.1 */ -int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) +int pthread_attr_setstacksize(pthread_attr_t *_attr, size_t stacksize) { + struct pthread_attr *attr = (struct pthread_attr *)_attr; + if ((attr == NULL) || (attr->initialized == 0U)) { return EINVAL; } @@ -602,9 +616,10 @@ int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) * * See IEEE 1003.1 */ -int pthread_attr_getstack(const pthread_attr_t *attr, - void **stackaddr, size_t *stacksize) +int pthread_attr_getstack(const pthread_attr_t *_attr, void **stackaddr, size_t *stacksize) { + const struct pthread_attr *attr = (const struct pthread_attr *)_attr; + if ((attr == NULL) || (attr->initialized == 0U)) { return EINVAL; } @@ -619,9 +634,10 @@ int pthread_attr_getstack(const pthread_attr_t *attr, * * See IEEE 1003.1 */ -int pthread_attr_getschedparam(const pthread_attr_t *attr, - struct sched_param *schedparam) +int pthread_attr_getschedparam(const pthread_attr_t *_attr, struct sched_param *schedparam) { + struct pthread_attr *attr = (struct pthread_attr *)_attr; + if ((attr == NULL) || (attr->initialized == 0U)) { return EINVAL; } @@ -635,8 +651,10 @@ int pthread_attr_getschedparam(const pthread_attr_t *attr, * * See IEEE 1003.1 */ -int pthread_attr_destroy(pthread_attr_t *attr) +int pthread_attr_destroy(pthread_attr_t *_attr) { + struct pthread_attr *attr = (struct pthread_attr *)_attr; + if ((attr != NULL) && (attr->initialized != 0U)) { attr->initialized = false; return 0; diff --git a/lib/posix/pthread_mutex.c b/lib/posix/pthread_mutex.c index 17abffe61af..2d514b6886c 100644 --- a/lib/posix/pthread_mutex.c +++ b/lib/posix/pthread_mutex.c @@ -21,7 +21,7 @@ int64_t timespec_to_timeoutms(const struct timespec *abstime); /* * Default mutex attrs. */ -static const pthread_mutexattr_t def_attr = { +static const struct pthread_mutexattr def_attr = { .type = PTHREAD_MUTEX_DEFAULT, }; @@ -174,11 +174,11 @@ int pthread_mutex_timedlock(pthread_mutex_t *m, * * See IEEE 1003.1 */ -int pthread_mutex_init(pthread_mutex_t *mu, - const pthread_mutexattr_t *attr) +int pthread_mutex_init(pthread_mutex_t *mu, const pthread_mutexattr_t *_attr) { k_spinlock_key_t key; struct posix_mutex *m; + const struct pthread_mutexattr *attr = (const struct pthread_mutexattr *)_attr; *mu = PTHREAD_MUTEX_INITIALIZER; key = k_spin_lock(&z_pthread_spinlock); @@ -301,8 +301,9 @@ int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, * * See IEEE 1003.1 */ -int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) +int pthread_mutexattr_gettype(const pthread_mutexattr_t *_attr, int *type) { + const struct pthread_mutexattr *attr = (const struct pthread_mutexattr *)_attr; *type = attr->type; return 0; } @@ -312,8 +313,9 @@ int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) * * See IEEE 1003.1 */ -int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) +int pthread_mutexattr_settype(pthread_mutexattr_t *_attr, int type) { + struct pthread_mutexattr *attr = (struct pthread_mutexattr *)_attr; int retc = EINVAL; if ((type == PTHREAD_MUTEX_NORMAL) ||