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:
Chris Friedt 2022-10-30 07:27:44 -04:00 committed by Stephanos Ioannidis
parent 3a3cfbb652
commit ce054404a2
7 changed files with 74 additions and 46 deletions

View file

@ -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;

View file

@ -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.

View 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

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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, &param), 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, &param), ESRCH,
zassert_equal(pthread_getschedparam(PTHREAD_INVALID, &policy, &param), ESRCH,
"get schedparam with NULL error");
zassert_equal(pthread_setschedparam(NULL, policy, &param), ESRCH,
zassert_equal(pthread_setschedparam(PTHREAD_INVALID, policy, &param), ESRCH,
"set schedparam with NULL error");
attr.initialized = 0U;