From ab5db3498122614def2e7707abad03c5098d56fa Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 2 Feb 2024 22:23:44 +0900 Subject: [PATCH] posix: Implement set and get inheritsched APIs for pthread attr Implement `pthread_attr_setinheritsched()` and `pthread_attr_getinheritsched()`are required as part of _POSIX_THREAD_PRIORITY_SCHEDULING Option Group. signed-off-by: Gaetan Perrot --- include/zephyr/posix/pthread.h | 8 +++++ lib/posix/options/posix_internal.h | 1 + lib/posix/options/pthread.c | 54 ++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/include/zephyr/posix/pthread.h b/include/zephyr/posix/pthread.h index 9b34c319b57e6ca..77ed22519a87781 100644 --- a/include/zephyr/posix/pthread.h +++ b/include/zephyr/posix/pthread.h @@ -39,6 +39,12 @@ extern "C" { #define PTHREAD_CANCEL_DEFERRED 0 #define PTHREAD_CANCEL_ASYNCHRONOUS 1 +/* Pthread inherit scheduler */ +#undef PTHREAD_INHERIT_SCHED +#define PTHREAD_INHERIT_SCHED 0 +#undef PTHREAD_EXPLICIT_SCHED +#define PTHREAD_EXPLICIT_SCHED 1 + /* Passed to pthread_once */ #define PTHREAD_ONCE_INIT {0} @@ -429,6 +435,8 @@ int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize); int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); +int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched); +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); #ifdef CONFIG_PTHREAD_IPC int pthread_once(pthread_once_t *once, void (*initFunc)(void)); #endif diff --git a/lib/posix/options/posix_internal.h b/lib/posix/options/posix_internal.h index 17d8c29d43852ec..46de27a49b7e885 100644 --- a/lib/posix/options/posix_internal.h +++ b/lib/posix/options/posix_internal.h @@ -29,6 +29,7 @@ struct posix_thread_attr { uint16_t guardsize : CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_BITS; int8_t priority; uint8_t schedpolicy: 2; + bool inheritsched: 1; union { bool caller_destroys: 1; bool initialized: 1; diff --git a/lib/posix/options/pthread.c b/lib/posix/options/pthread.c index 98761f7406465b2..e9c5dc2d694f5c1 100644 --- a/lib/posix/options/pthread.c +++ b/lib/posix/options/pthread.c @@ -384,6 +384,45 @@ int pthread_attr_setstack(pthread_attr_t *_attr, void *stackaddr, size_t stacksi return 0; } +/** + * @brief Get inherit scheduler attributes in thread attributes object. + * + * See IEEE 1003.1 + */ +int pthread_attr_getinheritsched(const pthread_attr_t *_attr, int *inheritsched) +{ +struct posix_thread_attr *attr = (struct posix_thread_attr *)_attr; + + if (!__attr_is_initialized(attr) || inheritsched == NULL) { + return EINVAL; + } + *inheritsched = attr->inheritsched; + return 0; +} + +/** + * @brief Set inherit scheduler attributes in thread attributes object. + * + * See IEEE 1003.1 + */ +int pthread_attr_setinheritsched(pthread_attr_t *_attr, int inheritsched) +{ + struct posix_thread_attr *attr = (struct posix_thread_attr *)_attr; + + if (!__attr_is_initialized(attr)) { + LOG_DBG("attr %p is not initialized", attr); + return EINVAL; + } + + if (inheritsched != PTHREAD_INHERIT_SCHED && inheritsched != PTHREAD_EXPLICIT_SCHED) { + LOG_DBG("Invalid inheritsched %d", inheritsched); + return EINVAL; + } + + attr->inheritsched = inheritsched; + return 0; +} + static void posix_thread_recycle_work_handler(struct k_work *work) { ARG_UNUSED(work); @@ -556,6 +595,20 @@ int pthread_create(pthread_t *th, const pthread_attr_t *_attr, void *(*threadrou t->attr = *(struct posix_thread_attr *)_attr; } + struct posix_thread *self = NULL; + + K_SPINLOCK(&pthread_pool_lock) { + self = to_posix_thread(pthread_self()); + if (self == NULL) { + K_SPINLOCK_BREAK; + } + if (self_attr.inheritsched == PTHREAD_INHERIT_SCHED) { + t->attr.priority = self->attr.priority; + t->attr.schedpolicy = self->attr.schedpolicy; + t->attr.inheritsched = self->attr.inheritsched; + } + } + /* spawn the thread */ k_thread_create( &t->thread, t->attr.stack, __get_attr_stacksize(&t->attr) + t->attr.guardsize, @@ -797,6 +850,7 @@ int pthread_attr_init(pthread_attr_t *_attr) *attr = (struct posix_thread_attr){0}; attr->guardsize = CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_DEFAULT; + attr->inheritsched = PTHREAD_INHERIT_SCHED; if (DYNAMIC_STACK_SIZE > 0) { attr->stack = k_thread_stack_alloc(DYNAMIC_STACK_SIZE + attr->guardsize,