From 8adb48e14d29abb877d7ae3de4fe17b80c657a76 Mon Sep 17 00:00:00 2001 From: Kinte <664060402@qq.com> Date: Tue, 1 Apr 2025 15:01:21 +0800 Subject: [PATCH] [feat](pthread): Add pthread_mutex_timedlock [Descriptions]: 1. Support POSIX pthread extension function pthread_mutex_timedlock 2. Format the files --- components/libc/posix/pthreads/pthread.c | 89 +++++------ components/libc/posix/pthreads/pthread.h | 141 +++++++++--------- .../libc/posix/pthreads/pthread_mutex.c | 62 ++++++++ 3 files changed, 178 insertions(+), 114 deletions(-) diff --git a/components/libc/posix/pthreads/pthread.c b/components/libc/posix/pthreads/pthread.c index 841bba5c5ac..e61f3f251e6 100644 --- a/components/libc/posix/pthreads/pthread.c +++ b/components/libc/posix/pthreads/pthread.c @@ -21,7 +21,7 @@ RT_DEFINE_HW_SPINLOCK(pth_lock); _pthread_data_t *pth_table[PTHREAD_NUM_MAX] = {NULL}; -static int concurrency_level; +static int concurrency_level; _pthread_data_t *_pthread_get_data(pthread_t thread) { @@ -43,7 +43,7 @@ pthread_t _pthread_data_get_pth(_pthread_data_t *ptd) int index; rt_hw_spin_lock(&pth_lock); - for (index = 0; index < PTHREAD_NUM_MAX; index ++) + for (index = 0; index < PTHREAD_NUM_MAX; index++) { if (pth_table[index] == ptd) break; } @@ -54,20 +54,20 @@ pthread_t _pthread_data_get_pth(_pthread_data_t *ptd) pthread_t _pthread_data_create(void) { - int index; + int index; _pthread_data_t *ptd = NULL; - ptd = (_pthread_data_t*)rt_malloc(sizeof(_pthread_data_t)); + ptd = (_pthread_data_t *)rt_malloc(sizeof(_pthread_data_t)); if (!ptd) return PTHREAD_NUM_MAX; memset(ptd, 0x0, sizeof(_pthread_data_t)); - ptd->canceled = 0; + ptd->canceled = 0; ptd->cancelstate = PTHREAD_CANCEL_DISABLE; - ptd->canceltype = PTHREAD_CANCEL_DEFERRED; - ptd->magic = PTHREAD_MAGIC; + ptd->canceltype = PTHREAD_CANCEL_DEFERRED; + ptd->magic = PTHREAD_MAGIC; rt_hw_spin_lock(&pth_lock); - for (index = 0; index < PTHREAD_NUM_MAX; index ++) + for (index = 0; index < PTHREAD_NUM_MAX; index++) { if (pth_table[index] == NULL) { @@ -90,7 +90,7 @@ pthread_t _pthread_data_create(void) static inline void _destroy_item(int index, _pthread_data_t *ptd) { extern _pthread_key_data_t _thread_keys[PTHREAD_KEY_MAX]; - void *data; + void *data; if (_thread_keys[index].is_used) { @@ -103,7 +103,7 @@ static inline void _destroy_item(int index, _pthread_data_t *ptd) } #ifdef RT_USING_CPLUSPLUS11 - #define NOT_USE_CXX_TLS -1 +#define NOT_USE_CXX_TLS -1 #endif void _pthread_data_destroy(_pthread_data_t *ptd) @@ -123,7 +123,7 @@ void _pthread_data_destroy(_pthread_data_t *ptd) * destructors of C++ object must be called safely. */ extern pthread_key_t emutls_get_pthread_key(void); - pthread_key_t emutls_pthread_key = emutls_get_pthread_key(); + pthread_key_t emutls_pthread_key = emutls_get_pthread_key(); if (emutls_pthread_key != NOT_USE_CXX_TLS) { @@ -131,8 +131,8 @@ void _pthread_data_destroy(_pthread_data_t *ptd) * Destructors of c++ class object must be called before emutls_key_destructor. */ int start = ((emutls_pthread_key - 1 + PTHREAD_KEY_MAX) % PTHREAD_KEY_MAX); - int i = 0; - for (index = start; i < PTHREAD_KEY_MAX; index = (index - 1 + PTHREAD_KEY_MAX) % PTHREAD_KEY_MAX, i ++) + int i = 0; + for (index = start; i < PTHREAD_KEY_MAX; index = (index - 1 + PTHREAD_KEY_MAX) % PTHREAD_KEY_MAX, i++) { _destroy_item(index, ptd); } @@ -143,7 +143,7 @@ void _pthread_data_destroy(_pthread_data_t *ptd) /* If only C TLS is used, that is, POSIX TLS or __Thread_local, * just iterate the _thread_keys from index 0. */ - for (index = 0; index < PTHREAD_KEY_MAX; index ++) + for (index = 0; index < PTHREAD_KEY_MAX; index++) { _destroy_item(index, ptd); } @@ -153,7 +153,7 @@ void _pthread_data_destroy(_pthread_data_t *ptd) ptd->tls = RT_NULL; } - pth = _pthread_data_get_pth(ptd); + pth = _pthread_data_get_pth(ptd); /* remove from pthread table */ rt_hw_spin_lock(&pth_lock); pth_table[pth] = NULL; @@ -191,7 +191,7 @@ static void _pthread_cleanup(rt_thread_t tid) static void pthread_entry_stub(void *parameter) { - void *value; + void *value; _pthread_data_t *ptd; ptd = (_pthread_data_t *)parameter; @@ -253,12 +253,12 @@ int pthread_create(pthread_t *pid, const pthread_attr_t *attr, void *(*start)(void *), void *parameter) { - int ret = 0; - void *stack; - char name[RT_NAME_MAX]; + int ret = 0; + void *stack; + char name[RT_NAME_MAX]; static rt_uint16_t pthread_number = 0; - pthread_t pth_id; + pthread_t pth_id; _pthread_data_t *ptd; /* pid shall be provided */ @@ -292,10 +292,10 @@ int pthread_create(pthread_t *pid, goto __exit; } - rt_snprintf(name, sizeof(name), "pth%02d", pthread_number ++); + rt_snprintf(name, sizeof(name), "pth%02d", pthread_number++); /* pthread is a static thread object */ - ptd->tid = (rt_thread_t) rt_malloc(sizeof(struct rt_thread)); + ptd->tid = (rt_thread_t)rt_malloc(sizeof(struct rt_thread)); if (ptd->tid == RT_NULL) { ret = ENOMEM; @@ -318,7 +318,7 @@ int pthread_create(pthread_t *pid, } /* set parameter */ - ptd->thread_entry = start; + ptd->thread_entry = start; ptd->thread_parameter = parameter; /* stack */ @@ -340,7 +340,8 @@ int pthread_create(pthread_t *pid, /* initial this pthread to system */ if (rt_thread_init(ptd->tid, name, pthread_entry_stub, ptd, stack, ptd->attr.stacksize, - ptd->attr.schedparam.sched_priority, 20) != RT_EOK) + ptd->attr.schedparam.sched_priority, 20) + != RT_EOK) { ret = EINVAL; goto __exit; @@ -350,7 +351,7 @@ int pthread_create(pthread_t *pid, *pid = pth_id; /* set pthread cleanup function and ptd data */ - ptd->tid->cleanup = _pthread_cleanup; + ptd->tid->cleanup = _pthread_cleanup; ptd->tid->pthread_data = (void *)ptd; /* start thread */ @@ -394,7 +395,7 @@ RTM_EXPORT(pthread_create); */ int pthread_detach(pthread_t thread) { - int ret = 0; + int ret = 0; _pthread_data_t *ptd = _pthread_get_data(thread); if (ptd == RT_NULL) { @@ -466,7 +467,7 @@ RTM_EXPORT(pthread_detach); int pthread_join(pthread_t thread, void **value_ptr) { _pthread_data_t *ptd; - rt_err_t result; + rt_err_t result; ptd = _pthread_get_data(thread); @@ -524,9 +525,9 @@ RTM_EXPORT(pthread_join); * * @see pthread_create, pthread_equal, pthread_join */ -pthread_t pthread_self (void) +pthread_t pthread_self(void) { - rt_thread_t tid; + rt_thread_t tid; _pthread_data_t *ptd; tid = rt_thread_self(); @@ -568,7 +569,7 @@ RTM_EXPORT(pthread_self); */ int pthread_getcpuclockid(pthread_t thread, clockid_t *clock_id) { - if(_pthread_get_data(thread) == NULL) + if (_pthread_get_data(thread) == NULL) { return EINVAL; } @@ -777,10 +778,10 @@ RTM_EXPORT(pthread_setschedparam); */ int pthread_setschedprio(pthread_t thread, int prio) { - _pthread_data_t *ptd; + _pthread_data_t *ptd; struct sched_param param; - ptd = _pthread_get_data(thread); + ptd = _pthread_get_data(thread); param.sched_priority = prio; pthread_attr_setschedparam(&ptd->attr, ¶m); @@ -808,9 +809,9 @@ RTM_EXPORT(pthread_setschedprio); */ void pthread_exit(void *value) { - _pthread_data_t *ptd; + _pthread_data_t *ptd; _pthread_cleanup_t *cleanup; - rt_thread_t tid; + rt_thread_t tid; if (rt_thread_self() == RT_NULL) { @@ -833,7 +834,7 @@ void pthread_exit(void *value) */ while (ptd->cleanup != RT_NULL) { - cleanup = ptd->cleanup; + cleanup = ptd->cleanup; ptd->cleanup = cleanup->next; cleanup->cleanup_func(cleanup->parameter); @@ -956,7 +957,7 @@ int pthread_kill(pthread_t thread, int sig) { #ifdef RT_USING_SIGNALS _pthread_data_t *ptd; - int ret; + int ret; ptd = _pthread_get_data(thread); if (ptd) @@ -1036,7 +1037,7 @@ int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) */ void pthread_cleanup_pop(int execute) { - _pthread_data_t *ptd; + _pthread_data_t *ptd; _pthread_cleanup_t *cleanup; if (rt_thread_self() == NULL) return; @@ -1092,7 +1093,7 @@ RTM_EXPORT(pthread_cleanup_pop); */ void pthread_cleanup_push(void (*routine)(void *), void *arg) { - _pthread_data_t *ptd; + _pthread_data_t *ptd; _pthread_cleanup_t *cleanup; if (rt_thread_self() == NULL) return; @@ -1105,11 +1106,11 @@ void pthread_cleanup_push(void (*routine)(void *), void *arg) if (cleanup != RT_NULL) { cleanup->cleanup_func = routine; - cleanup->parameter = arg; + cleanup->parameter = arg; rt_enter_critical(); cleanup->next = ptd->cleanup; - ptd->cleanup = cleanup; + ptd->cleanup = cleanup; rt_exit_critical(); } } @@ -1261,7 +1262,7 @@ RTM_EXPORT(pthread_setcanceltype); */ void pthread_testcancel(void) { - int cancel = 0; + int cancel = 0; _pthread_data_t *ptd; if (rt_thread_self() == NULL) return; @@ -1303,9 +1304,9 @@ RTM_EXPORT(pthread_testcancel); */ int pthread_cancel(pthread_t thread) { - _pthread_data_t *ptd; + _pthread_data_t *ptd; _pthread_cleanup_t *cleanup; - rt_thread_t tid; + rt_thread_t tid; /* get posix thread data */ ptd = _pthread_get_data(thread); @@ -1331,7 +1332,7 @@ int pthread_cancel(pthread_t thread) */ while (ptd->cleanup != RT_NULL) { - cleanup = ptd->cleanup; + cleanup = ptd->cleanup; ptd->cleanup = cleanup->next; cleanup->cleanup_func(cleanup->parameter); diff --git a/components/libc/posix/pthreads/pthread.h b/components/libc/posix/pthreads/pthread.h index 1a27eae6e2e..882c3c21420 100644 --- a/components/libc/posix/pthreads/pthread.h +++ b/components/libc/posix/pthreads/pthread.h @@ -20,17 +20,17 @@ extern "C" { #include #include -#define PTHREAD_KEY_MAX 8 +#define PTHREAD_KEY_MAX 8 -#define PTHREAD_COND_INITIALIZER {-1} -#define PTHREAD_RWLOCK_INITIALIZER {-1} -#define PTHREAD_MUTEX_INITIALIZER {-1} +#define PTHREAD_COND_INITIALIZER {-1} +#define PTHREAD_RWLOCK_INITIALIZER {-1} +#define PTHREAD_MUTEX_INITIALIZER {-1} -#define PTHREAD_CREATE_JOINABLE 0x00 -#define PTHREAD_CREATE_DETACHED 0x01 +#define PTHREAD_CREATE_JOINABLE 0x00 +#define PTHREAD_CREATE_DETACHED 0x01 -#define PTHREAD_EXPLICIT_SCHED 0 -#define PTHREAD_INHERIT_SCHED 1 +#define PTHREAD_EXPLICIT_SCHED 0 +#define PTHREAD_INHERIT_SCHED 1 typedef long pthread_t; typedef long pthread_condattr_t; @@ -52,29 +52,29 @@ enum enum { - PTHREAD_MUTEX_NORMAL = 0, - PTHREAD_MUTEX_RECURSIVE = 1, - PTHREAD_MUTEX_ERRORCHECK = 2, + PTHREAD_MUTEX_NORMAL = 0, + PTHREAD_MUTEX_RECURSIVE = 1, + PTHREAD_MUTEX_ERRORCHECK = 2, PTHREAD_MUTEX_ERRORCHECK_NP = PTHREAD_MUTEX_ERRORCHECK, PTHREAD_MUTEX_RECURSIVE_NP = PTHREAD_MUTEX_RECURSIVE, - PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL }; /* init value for pthread_once_t */ -#define PTHREAD_ONCE_INIT 0 +#define PTHREAD_ONCE_INIT 0 enum { - PTHREAD_PRIO_INHERIT =0, + PTHREAD_PRIO_INHERIT = 0, PTHREAD_PRIO_NONE, PTHREAD_PRIO_PROTECT, }; -#define PTHREAD_PROCESS_PRIVATE 0 -#define PTHREAD_PROCESS_SHARED 1 +#define PTHREAD_PROCESS_PRIVATE 0 +#define PTHREAD_PROCESS_SHARED 1 -#define PTHREAD_SCOPE_PROCESS 0 -#define PTHREAD_SCOPE_SYSTEM 1 +#define PTHREAD_SCOPE_PROCESS 0 +#define PTHREAD_SCOPE_SYSTEM 1 struct sched_param { @@ -83,27 +83,27 @@ struct sched_param struct pthread_attr { - void* stackaddr; /* stack address of thread */ - int stacksize; /* stack size of thread */ + void *stackaddr; /* stack address of thread */ + int stacksize; /* stack size of thread */ - int inheritsched; /* Inherit parent prio/policy */ - int schedpolicy; /* scheduler policy */ - struct sched_param schedparam; /* sched parameter */ + int inheritsched; /* Inherit parent prio/policy */ + int schedpolicy; /* scheduler policy */ + struct sched_param schedparam; /* sched parameter */ - int detachstate; /* detach state */ + int detachstate; /* detach state */ }; typedef struct pthread_attr pthread_attr_t; struct pthread_mutex { pthread_mutexattr_t attr; - struct rt_mutex lock; + struct rt_mutex lock; }; typedef struct pthread_mutex pthread_mutex_t; struct pthread_cond { - pthread_condattr_t attr; + pthread_condattr_t attr; struct rt_semaphore sem; }; typedef struct pthread_cond pthread_cond_t; @@ -112,13 +112,13 @@ struct pthread_rwlock { pthread_rwlockattr_t attr; - pthread_mutex_t rw_mutex; /* basic lock on this struct */ - pthread_cond_t rw_condreaders; /* for reader threads waiting */ - pthread_cond_t rw_condwriters; /* for writer threads waiting */ + pthread_mutex_t rw_mutex; /* basic lock on this struct */ + pthread_cond_t rw_condreaders; /* for reader threads waiting */ + pthread_cond_t rw_condwriters; /* for writer threads waiting */ - int rw_nwaitreaders; /* the number of reader threads waiting */ - int rw_nwaitwriters; /* the number of writer threads waiting */ - int rw_refcount; /* 0: unlocked, -1: locked by writer, > 0 locked by n readers */ + int rw_nwaitreaders; /* the number of reader threads waiting */ + int rw_nwaitwriters; /* the number of writer threads waiting */ + int rw_refcount; /* 0: unlocked, -1: locked by writer, > 0 locked by n readers */ }; typedef struct pthread_rwlock pthread_rwlock_t; @@ -131,8 +131,8 @@ typedef struct pthread_spinlock pthread_spinlock_t; struct pthread_barrier { - int count; - pthread_cond_t cond; + int count; + pthread_cond_t cond; pthread_mutex_t mutex; }; typedef struct pthread_barrier pthread_barrier_t; @@ -144,8 +144,8 @@ int pthread_attr_setdetachstate(pthread_attr_t *attr, int state); int pthread_attr_getdetachstate(pthread_attr_t const *attr, int *state); int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); int pthread_attr_getschedpolicy(pthread_attr_t const *attr, int *policy); -int pthread_attr_setschedparam(pthread_attr_t *attr,struct sched_param const *param); -int pthread_attr_getschedparam(pthread_attr_t const *attr,struct sched_param *param); +int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param const *param); +int pthread_attr_getschedparam(pthread_attr_t const *attr, struct sched_param *param); int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size); int pthread_attr_getstacksize(pthread_attr_t const *attr, size_t *stack_size); int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack_addr); @@ -162,18 +162,18 @@ int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched); int pthread_attr_setscope(pthread_attr_t *attr, int scope); int pthread_attr_getscope(pthread_attr_t const *attr, int *scope); -int pthread_create (pthread_t *tid, const pthread_attr_t *attr, - void *(*start) (void *), void *arg); +int pthread_create(pthread_t *tid, const pthread_attr_t *attr, + void *(*start)(void *), void *arg); -int pthread_detach (pthread_t thread); -int pthread_join (pthread_t thread, void **value_ptr); +int pthread_detach(pthread_t thread); +int pthread_join(pthread_t thread, void **value_ptr); -rt_inline int pthread_equal (pthread_t t1, pthread_t t2) +rt_inline int pthread_equal(pthread_t t1, pthread_t t2) { return t1 == t2; } -pthread_t pthread_self (void); +pthread_t pthread_self(void); int pthread_getcpuclockid(pthread_t thread, clockid_t *clock_id); int pthread_getconcurrency(void); @@ -182,8 +182,8 @@ int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *par int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param); int pthread_setschedprio(pthread_t thread, int prio); -void pthread_exit (void *value_ptr); -int pthread_once(pthread_once_t * once_control, void (*init_routine) (void)); +void pthread_exit(void *value_ptr); +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); #ifdef RT_USING_SIGNALS int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset); @@ -191,13 +191,13 @@ int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset); /* pthread cleanup */ void pthread_cleanup_pop(int execute); -void pthread_cleanup_push(void (*routine)(void*), void *arg); +void pthread_cleanup_push(void (*routine)(void *), void *arg); /* pthread cancel */ -int pthread_cancel(pthread_t thread); +int pthread_cancel(pthread_t thread); void pthread_testcancel(void); -int pthread_setcancelstate(int state, int *oldstate); -int pthread_setcanceltype(int type, int *oldtype); +int pthread_setcancelstate(int state, int *oldstate); +int pthread_setcanceltype(int type, int *oldtype); int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)); int pthread_kill(pthread_t thread, int sig); @@ -208,6 +208,7 @@ int pthread_mutex_destroy(pthread_mutex_t *mutex); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); +int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime); int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, int *prioceiling); int pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling, int *old_ceiling); @@ -215,7 +216,7 @@ int pthread_mutexattr_init(pthread_mutexattr_t *attr); int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type); int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); -int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared); +int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared); int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared); int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *prioceiling); int pthread_mutexattr_setprioceiling(const pthread_mutexattr_t *attr, int prioceiling); @@ -244,32 +245,32 @@ int pthread_cond_timedwait(pthread_cond_t *cond, const struct timespec *abstime); /* pthread rwlock interface */ -int pthread_rwlockattr_init (pthread_rwlockattr_t *attr); -int pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr); -int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared); -int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared); +int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *pshared); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared); -int pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); -int pthread_rwlock_destroy (pthread_rwlock_t *rwlock); +int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); +int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); -int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock); -int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock); +int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); +int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); -int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock, const struct timespec *abstime); -int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, const struct timespec *abstime); +int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, const struct timespec *abstime); +int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *abstime); -int pthread_rwlock_unlock (pthread_rwlock_t *rwlock); +int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); -int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock); -int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock); +int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); +int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); /* pthread spinlock interface */ -int pthread_spin_init (pthread_spinlock_t *lock, int pshared); -int pthread_spin_destroy (pthread_spinlock_t *lock); +int pthread_spin_init(pthread_spinlock_t *lock, int pshared); +int pthread_spin_destroy(pthread_spinlock_t *lock); -int pthread_spin_lock (pthread_spinlock_t * lock); -int pthread_spin_trylock (pthread_spinlock_t * lock); -int pthread_spin_unlock (pthread_spinlock_t * lock); +int pthread_spin_lock(pthread_spinlock_t *lock); +int pthread_spin_trylock(pthread_spinlock_t *lock); +int pthread_spin_unlock(pthread_spinlock_t *lock); /* pthread barrier interface */ int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); @@ -284,10 +285,10 @@ int pthread_barrier_init(pthread_barrier_t *barrier, int pthread_barrier_wait(pthread_barrier_t *barrier); -int pthread_setspecific(pthread_key_t key, const void *value); +int pthread_setspecific(pthread_key_t key, const void *value); void *pthread_getspecific(pthread_key_t key); -int pthread_key_create(pthread_key_t *key, void (*destructor)(void *)); -int pthread_key_delete(pthread_key_t key); +int pthread_key_create(pthread_key_t *key, void (*destructor)(void *)); +int pthread_key_delete(pthread_key_t key); #ifdef __cplusplus } diff --git a/components/libc/posix/pthreads/pthread_mutex.c b/components/libc/posix/pthreads/pthread_mutex.c index ba433b2281d..f8332fe265e 100644 --- a/components/libc/posix/pthreads/pthread_mutex.c +++ b/components/libc/posix/pthreads/pthread_mutex.c @@ -541,6 +541,68 @@ int pthread_mutex_trylock(pthread_mutex_t *mutex) } RTM_EXPORT(pthread_mutex_trylock); + +/** + * @brief Attempts to lock a mutex with a timeout. + * + * This function attempts to lock the mutex object pointed to by `mutex`. If the mutex + * is already locked by another thread, the function will block until the mutex becomes + * available or the specified timeout occurs. + * + * @param[in,out] mutex Pointer to the mutex to be locked. + * @param[in] abstime Pointer to a `struct timespec` structure specifying the absolute time + * when the function should return if the mutex is not available. + * + * @return + * - 0 on success. + * - Non-zero error code on failure, including: + * - `EINVAL`: The mutex is invalid or uninitialized. + * - `EDEADLK`: A deadlock condition was detected (e.g., the current thread + * already holds the mutex in a recursive locking scenario). + * + * @note + * This function is useful for implementing timed mutex acquisition. If the mutex + * was initialized with the `PTHREAD_MUTEX_RECURSIVE` attribute, the calling thread can + * lock it multiple times, but must unlock it the same number of times. + * + * @warning + * Attempting to timedlock an uninitialized or destroyed mutex results in undefined behavior. + * + * @see pthread_mutex_lock, pthread_mutex_unlock, pthread_mutex_trylock, pthread_mutex_init + */ +int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime) +{ + int mtype; + rt_err_t result; + + if (!mutex) + return EINVAL; + + if (mutex->attr == -1) + { + /* init mutex */ + pthread_mutex_init(mutex, RT_NULL); + } + + mtype = mutex->attr & MUTEXATTR_TYPE_MASK; + rt_enter_critical(); + if (mutex->lock.owner == rt_thread_self() && mtype != PTHREAD_MUTEX_RECURSIVE) + { + rt_exit_critical(); + return EDEADLK; + } + rt_exit_critical(); + + rt_int32_t timeout = rt_timespec_to_tick(abstime); + + result = rt_mutex_take(&(mutex->lock), timeout); + if (result == RT_EOK) + return 0; + + return EINVAL; +} +RTM_EXPORT(pthread_mutex_timedlock); + int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *prioceiling) { return EINVAL;