posix: use uint32_t instead of void* for pthread_t
Several other widely-used pthread implementations abstract `pthread_t` as `uint32_t`. The benefit there is that we avoid passing around a pointer to an internal structure (implementation detail). Additionally, this removes the alias from `k_tid_t` to `pthread_t` inside of `struct pthread_mutex`. Signed-off-by: Chris Friedt <cfriedt@meta.com>
This commit is contained in:
parent
3a3cfbb652
commit
ce054404a2
|
@ -44,14 +44,14 @@ typedef struct pthread_attr {
|
|||
uint32_t initialized;
|
||||
} pthread_attr_t;
|
||||
|
||||
typedef void *pthread_t;
|
||||
typedef uint32_t pthread_t;
|
||||
|
||||
/* Semaphore */
|
||||
typedef struct k_sem sem_t;
|
||||
|
||||
/* Mutex */
|
||||
typedef struct pthread_mutex {
|
||||
pthread_t owner;
|
||||
k_tid_t owner;
|
||||
uint16_t lock_count;
|
||||
int type;
|
||||
_wait_q_t wait_q;
|
||||
|
|
|
@ -447,11 +447,7 @@ int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
|
|||
*
|
||||
* See IEEE 1003.1
|
||||
*/
|
||||
static inline pthread_t pthread_self(void)
|
||||
{
|
||||
return (pthread_t)k_current_get();
|
||||
}
|
||||
|
||||
pthread_t pthread_self(void);
|
||||
|
||||
/**
|
||||
* @brief Compare thread IDs.
|
||||
|
|
12
lib/posix/posix_internal.h
Normal file
12
lib/posix/posix_internal.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Meta
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_LIB_POSIX_POSIX_INTERNAL_H_
|
||||
#define ZEPHYR_LIB_POSIX_POSIX_INTERNAL_H_
|
||||
|
||||
struct posix_thread *to_posix_thread(pthread_t pthread);
|
||||
|
||||
#endif
|
|
@ -12,6 +12,8 @@
|
|||
#include <zephyr/posix/pthread.h>
|
||||
#include <zephyr/sys/slist.h>
|
||||
|
||||
#include "posix_internal.h"
|
||||
|
||||
#define PTHREAD_INIT_FLAGS PTHREAD_CANCEL_ENABLE
|
||||
#define PTHREAD_CANCELED ((void *) -1)
|
||||
|
||||
|
@ -37,6 +39,22 @@ static const pthread_attr_t init_pthread_attrs = {
|
|||
static struct posix_thread posix_thread_pool[CONFIG_MAX_PTHREAD_COUNT];
|
||||
PTHREAD_MUTEX_DEFINE(pthread_pool_lock);
|
||||
|
||||
pthread_t pthread_self(void)
|
||||
{
|
||||
return (struct posix_thread *)
|
||||
CONTAINER_OF(k_current_get(), struct posix_thread, thread)
|
||||
- posix_thread_pool;
|
||||
}
|
||||
|
||||
struct posix_thread *to_posix_thread(pthread_t pthread)
|
||||
{
|
||||
if (pthread >= CONFIG_MAX_PTHREAD_COUNT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &posix_thread_pool[pthread];
|
||||
}
|
||||
|
||||
static bool is_posix_prio_valid(uint32_t priority, int policy)
|
||||
{
|
||||
if (priority >= sched_get_priority_min(policy) &&
|
||||
|
@ -183,14 +201,10 @@ int pthread_create(pthread_t *newthread, const pthread_attr_t *attr,
|
|||
pthread_cond_init(&thread->state_cond, &cond_attr);
|
||||
sys_slist_init(&thread->key_list);
|
||||
|
||||
*newthread = (pthread_t) k_thread_create(&thread->thread, attr->stack,
|
||||
attr->stacksize,
|
||||
(k_thread_entry_t)
|
||||
zephyr_thread_wrapper,
|
||||
(void *)arg, NULL,
|
||||
threadroutine, prio,
|
||||
(~K_ESSENTIAL & attr->flags),
|
||||
K_MSEC(attr->delayedstart));
|
||||
*newthread = pthread_num;
|
||||
k_thread_create(&thread->thread, attr->stack, attr->stacksize,
|
||||
(k_thread_entry_t)zephyr_thread_wrapper, (void *)arg, NULL, threadroutine,
|
||||
prio, (~K_ESSENTIAL & attr->flags), K_MSEC(attr->delayedstart));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -202,7 +216,7 @@ int pthread_create(pthread_t *newthread, const pthread_attr_t *attr,
|
|||
*/
|
||||
int pthread_setcancelstate(int state, int *oldstate)
|
||||
{
|
||||
struct posix_thread *pthread = (struct posix_thread *) pthread_self();
|
||||
struct posix_thread *pthread = to_posix_thread(pthread_self());
|
||||
|
||||
if (state != PTHREAD_CANCEL_ENABLE &&
|
||||
state != PTHREAD_CANCEL_DISABLE) {
|
||||
|
@ -229,7 +243,7 @@ int pthread_setcancelstate(int state, int *oldstate)
|
|||
*/
|
||||
int pthread_cancel(pthread_t pthread)
|
||||
{
|
||||
struct posix_thread *thread = (struct posix_thread *) pthread;
|
||||
struct posix_thread *thread = to_posix_thread(pthread);
|
||||
int cancel_state;
|
||||
|
||||
if ((thread == NULL) || (thread->state == PTHREAD_TERMINATED)) {
|
||||
|
@ -252,7 +266,7 @@ int pthread_cancel(pthread_t pthread)
|
|||
}
|
||||
pthread_mutex_unlock(&thread->state_lock);
|
||||
|
||||
k_thread_abort((k_tid_t) thread);
|
||||
k_thread_abort(&thread->thread);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -266,7 +280,7 @@ int pthread_cancel(pthread_t pthread)
|
|||
int pthread_setschedparam(pthread_t pthread, int policy,
|
||||
const struct sched_param *param)
|
||||
{
|
||||
k_tid_t thread = (k_tid_t)pthread;
|
||||
struct posix_thread *thread = to_posix_thread(pthread);
|
||||
int new_prio;
|
||||
|
||||
if (thread == NULL) {
|
||||
|
@ -283,7 +297,7 @@ int pthread_setschedparam(pthread_t pthread, int policy,
|
|||
|
||||
new_prio = posix_to_zephyr_priority(param->sched_priority, policy);
|
||||
|
||||
k_thread_priority_set(thread, new_prio);
|
||||
k_thread_priority_set(&thread->thread, new_prio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -312,14 +326,14 @@ int pthread_attr_init(pthread_attr_t *attr)
|
|||
int pthread_getschedparam(pthread_t pthread, int *policy,
|
||||
struct sched_param *param)
|
||||
{
|
||||
struct posix_thread *thread = (struct posix_thread *) pthread;
|
||||
struct posix_thread *thread = to_posix_thread(pthread);
|
||||
uint32_t priority;
|
||||
|
||||
if ((thread == NULL) || (thread->state == PTHREAD_TERMINATED)) {
|
||||
return ESRCH;
|
||||
}
|
||||
|
||||
priority = k_thread_priority_get((k_tid_t) thread);
|
||||
priority = k_thread_priority_get(&thread->thread);
|
||||
|
||||
param->sched_priority = zephyr_to_posix_priority(priority, policy);
|
||||
return 0;
|
||||
|
@ -354,7 +368,7 @@ int pthread_once(pthread_once_t *once, void (*init_func)(void))
|
|||
*/
|
||||
void pthread_exit(void *retval)
|
||||
{
|
||||
struct posix_thread *self = (struct posix_thread *)pthread_self();
|
||||
struct posix_thread *self = to_posix_thread(pthread_self());
|
||||
pthread_key_obj *key_obj;
|
||||
pthread_thread_data *thread_spec_data;
|
||||
sys_snode_t *node_l;
|
||||
|
@ -397,17 +411,17 @@ void pthread_exit(void *retval)
|
|||
*/
|
||||
int pthread_join(pthread_t thread, void **status)
|
||||
{
|
||||
struct posix_thread *pthread = (struct posix_thread *) thread;
|
||||
struct posix_thread *pthread = to_posix_thread(thread);
|
||||
int ret = 0;
|
||||
|
||||
if (thread == pthread_self()) {
|
||||
return EDEADLK;
|
||||
}
|
||||
|
||||
if (pthread == NULL) {
|
||||
return ESRCH;
|
||||
}
|
||||
|
||||
if (pthread == pthread_self()) {
|
||||
return EDEADLK;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&pthread->state_lock);
|
||||
|
||||
if (pthread->state == PTHREAD_JOINABLE) {
|
||||
|
@ -435,7 +449,7 @@ int pthread_join(pthread_t thread, void **status)
|
|||
*/
|
||||
int pthread_detach(pthread_t thread)
|
||||
{
|
||||
struct posix_thread *pthread = (struct posix_thread *) thread;
|
||||
struct posix_thread *pthread = to_posix_thread(thread);
|
||||
int ret = 0;
|
||||
|
||||
if (pthread == NULL) {
|
||||
|
@ -621,12 +635,14 @@ int pthread_attr_destroy(pthread_attr_t *attr)
|
|||
int pthread_setname_np(pthread_t thread, const char *name)
|
||||
{
|
||||
#ifdef CONFIG_THREAD_NAME
|
||||
k_tid_t kthread = (k_tid_t)thread;
|
||||
k_tid_t kthread;
|
||||
|
||||
if (kthread == NULL) {
|
||||
if (thread >= CONFIG_MAX_PTHREAD_COUNT) {
|
||||
return ESRCH;
|
||||
}
|
||||
|
||||
kthread = &posix_thread_pool[thread].thread;
|
||||
|
||||
if (name == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
@ -642,9 +658,9 @@ int pthread_setname_np(pthread_t thread, const char *name)
|
|||
int pthread_getname_np(pthread_t thread, char *name, size_t len)
|
||||
{
|
||||
#ifdef CONFIG_THREAD_NAME
|
||||
k_tid_t kthread = (k_tid_t)thread;
|
||||
k_tid_t kthread;
|
||||
|
||||
if (kthread == NULL) {
|
||||
if (thread >= CONFIG_MAX_PTHREAD_COUNT) {
|
||||
return ESRCH;
|
||||
}
|
||||
|
||||
|
@ -653,6 +669,7 @@ int pthread_getname_np(pthread_t thread, char *name, size_t len)
|
|||
}
|
||||
|
||||
memset(name, '\0', len);
|
||||
kthread = &posix_thread_pool[thread].thread;
|
||||
return k_thread_name_copy(kthread, name, len-1);
|
||||
#else
|
||||
ARG_UNUSED(thread);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <zephyr/posix/pthread.h>
|
||||
#include <zephyr/posix/pthread_key.h>
|
||||
|
||||
#include "posix_internal.h"
|
||||
|
||||
struct k_sem pthread_key_sem;
|
||||
|
||||
K_SEM_DEFINE(pthread_key_sem, 1, 1);
|
||||
|
@ -77,7 +79,7 @@ int pthread_key_delete(pthread_key_t key)
|
|||
int pthread_setspecific(pthread_key_t key, const void *value)
|
||||
{
|
||||
pthread_key_obj *key_obj = (pthread_key_obj *)key;
|
||||
struct posix_thread *thread = (struct posix_thread *)pthread_self();
|
||||
struct posix_thread *thread = to_posix_thread(pthread_self());
|
||||
pthread_key_data *key_data;
|
||||
pthread_thread_data *thread_spec_data;
|
||||
sys_snode_t *node_l;
|
||||
|
@ -139,7 +141,7 @@ out:
|
|||
void *pthread_getspecific(pthread_key_t key)
|
||||
{
|
||||
pthread_key_obj *key_obj = (pthread_key_obj *)key;
|
||||
struct posix_thread *thread = (struct posix_thread *)pthread_self();
|
||||
struct posix_thread *thread = to_posix_thread(pthread_self());
|
||||
pthread_thread_data *thread_spec_data;
|
||||
void *value = NULL;
|
||||
sys_snode_t *node_l;
|
||||
|
|
|
@ -29,11 +29,11 @@ static int acquire_mutex(pthread_mutex_t *m, k_timeout_t timeout)
|
|||
|
||||
if (m->lock_count == 0U && m->owner == NULL) {
|
||||
m->lock_count++;
|
||||
m->owner = pthread_self();
|
||||
m->owner = k_current_get();
|
||||
|
||||
k_spin_unlock(&z_pthread_spinlock, key);
|
||||
return 0;
|
||||
} else if (m->owner == pthread_self()) {
|
||||
} else if (m->owner == k_current_get()) {
|
||||
if (m->type == PTHREAD_MUTEX_RECURSIVE &&
|
||||
m->lock_count < MUTEX_MAX_REC_LOCK) {
|
||||
m->lock_count++;
|
||||
|
@ -128,7 +128,7 @@ int pthread_mutex_unlock(pthread_mutex_t *m)
|
|||
|
||||
k_tid_t thread;
|
||||
|
||||
if (m->owner != pthread_self()) {
|
||||
if (m->owner != k_current_get()) {
|
||||
k_spin_unlock(&z_pthread_spinlock, key);
|
||||
return EPERM;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ int pthread_mutex_unlock(pthread_mutex_t *m)
|
|||
if (m->lock_count == 0U) {
|
||||
thread = z_unpend_first_thread(&m->wait_q);
|
||||
if (thread) {
|
||||
m->owner = (pthread_t)thread;
|
||||
m->owner = thread;
|
||||
m->lock_count++;
|
||||
arch_thread_return_value_set(thread, 0);
|
||||
z_ready_thread(thread);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define PTHREAD_CANCEL_INVALID -1
|
||||
#define SCHED_INVALID -1
|
||||
#define PRIO_INVALID -1
|
||||
#define PTHREAD_INVALID -1
|
||||
|
||||
K_THREAD_STACK_ARRAY_DEFINE(stack_e, N_THR_E, STACKS);
|
||||
K_THREAD_STACK_ARRAY_DEFINE(stack_t, N_THR_T, STACKS);
|
||||
|
@ -293,13 +294,13 @@ ZTEST(posix_apis, test_posix_pthread_execution)
|
|||
/* TESTPOINT: Try getting name of NULL thread (aka uninitialized
|
||||
* thread var).
|
||||
*/
|
||||
ret = pthread_getname_np(NULL, thr_name_buf, sizeof(thr_name_buf));
|
||||
ret = pthread_getname_np(PTHREAD_INVALID, thr_name_buf, sizeof(thr_name_buf));
|
||||
zassert_equal(ret, ESRCH, "uninitialized getname!");
|
||||
|
||||
/* TESTPOINT: Try setting name of NULL thread (aka uninitialized
|
||||
* thread var).
|
||||
*/
|
||||
ret = pthread_setname_np(NULL, thr_name);
|
||||
ret = pthread_setname_np(PTHREAD_INVALID, thr_name);
|
||||
zassert_equal(ret, ESRCH, "uninitialized setname!");
|
||||
|
||||
/* TESTPOINT: Try creating thread before attr init */
|
||||
|
@ -429,20 +430,20 @@ ZTEST(posix_apis, test_posix_pthread_error_condition)
|
|||
EINVAL, "pthread set detach state with NULL error");
|
||||
zassert_equal(pthread_attr_getdetachstate(NULL, &detach),
|
||||
EINVAL, "get detach state error");
|
||||
zassert_equal(pthread_detach(NULL), ESRCH, "detach with NULL error");
|
||||
zassert_equal(pthread_detach(PTHREAD_INVALID), ESRCH, "detach with NULL error");
|
||||
zassert_equal(pthread_attr_init(NULL), ENOMEM,
|
||||
"init with NULL error");
|
||||
zassert_equal(pthread_attr_setschedparam(NULL, ¶m), EINVAL,
|
||||
"set sched param with NULL error");
|
||||
zassert_equal(pthread_cancel(NULL), ESRCH,
|
||||
zassert_equal(pthread_cancel(PTHREAD_INVALID), ESRCH,
|
||||
"cancel NULL error");
|
||||
zassert_equal(pthread_join(NULL, NULL), ESRCH,
|
||||
zassert_equal(pthread_join(PTHREAD_INVALID, NULL), ESRCH,
|
||||
"join with NULL has error");
|
||||
zassert_false(pthread_once(&key, NULL),
|
||||
"pthread dynamic package initialization error");
|
||||
zassert_equal(pthread_getschedparam(NULL, &policy, ¶m), ESRCH,
|
||||
zassert_equal(pthread_getschedparam(PTHREAD_INVALID, &policy, ¶m), ESRCH,
|
||||
"get schedparam with NULL error");
|
||||
zassert_equal(pthread_setschedparam(NULL, policy, ¶m), ESRCH,
|
||||
zassert_equal(pthread_setschedparam(PTHREAD_INVALID, policy, ¶m), ESRCH,
|
||||
"set schedparam with NULL error");
|
||||
|
||||
attr.initialized = 0U;
|
||||
|
|
Loading…
Reference in a new issue