Skip to content

Commit 124f7c4

Browse files
committed
[feat](pthread): Add pthread_mutex_timedlock
[Descriptions]: 1. Support POSIX pthread extension function pthread_mutex_timedlock
1 parent 45eea78 commit 124f7c4

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

components/libc/posix/pthreads/pthread.h

+1
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ int pthread_mutex_destroy(pthread_mutex_t *mutex);
208208
int pthread_mutex_lock(pthread_mutex_t *mutex);
209209
int pthread_mutex_unlock(pthread_mutex_t *mutex);
210210
int pthread_mutex_trylock(pthread_mutex_t *mutex);
211+
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime);
211212
int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, int *prioceiling);
212213
int pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling, int *old_ceiling);
213214

components/libc/posix/pthreads/pthread_mutex.c

+62
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,68 @@ int pthread_mutex_trylock(pthread_mutex_t *mutex)
541541
}
542542
RTM_EXPORT(pthread_mutex_trylock);
543543

544+
545+
/**
546+
* @brief Attempts to lock a mutex with a timeout.
547+
*
548+
* This function attempts to lock the mutex object pointed to by `mutex`. If the mutex
549+
* is already locked by another thread, the function will block until the mutex becomes
550+
* available or the specified timeout occurs.
551+
*
552+
* @param[in,out] mutex Pointer to the mutex to be locked.
553+
* @param[in] abstime Pointer to a `struct timespec` structure specifying the absolute time
554+
* when the function should return if the mutex is not available.
555+
*
556+
* @return
557+
* - 0 on success.
558+
* - Non-zero error code on failure, including:
559+
* - `EINVAL`: The mutex is invalid or uninitialized.
560+
* - `EDEADLK`: A deadlock condition was detected (e.g., the current thread
561+
* already holds the mutex in a recursive locking scenario).
562+
*
563+
* @note
564+
* This function is useful for implementing timed mutex acquisition. If the mutex
565+
* was initialized with the `PTHREAD_MUTEX_RECURSIVE` attribute, the calling thread can
566+
* lock it multiple times, but must unlock it the same number of times.
567+
*
568+
* @warning
569+
* Attempting to timedlock an uninitialized or destroyed mutex results in undefined behavior.
570+
*
571+
* @see pthread_mutex_lock, pthread_mutex_unlock, pthread_mutex_trylock, pthread_mutex_init
572+
*/
573+
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime)
574+
{
575+
int mtype;
576+
rt_err_t result;
577+
578+
if (!mutex)
579+
return EINVAL;
580+
581+
if (mutex->attr == -1)
582+
{
583+
/* init mutex */
584+
pthread_mutex_init(mutex, RT_NULL);
585+
}
586+
587+
mtype = mutex->attr & MUTEXATTR_TYPE_MASK;
588+
rt_enter_critical();
589+
if (mutex->lock.owner == rt_thread_self() && mtype != PTHREAD_MUTEX_RECURSIVE)
590+
{
591+
rt_exit_critical();
592+
return EDEADLK;
593+
}
594+
rt_exit_critical();
595+
596+
rt_int32_t timeout = rt_timespec_to_tick(abstime);
597+
598+
result = rt_mutex_take(&(mutex->lock), timeout);
599+
if (result == RT_EOK)
600+
return 0;
601+
602+
return EINVAL;
603+
}
604+
RTM_EXPORT(pthread_mutex_timedlock);
605+
544606
int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *prioceiling)
545607
{
546608
return EINVAL;

0 commit comments

Comments
 (0)