Skip to content

Commit a71e0f2

Browse files
ClaCodeskartben
authored andcommitted
posix: pthread: implement non-standard try-join and timed-join
These functions can be used to join pthreads in a non-standard way. The function pthread_tryjoin will not block and simply test whether the thread has exited already. The function pthread_timed_join will only block until the specified time. The functions are wrappers for calling the k_thread_join with timeout K_NO_WAIT and with a specific timeout as opposed to calling it with K_FOREVER. Signed-off-by: Cla Galliard <[email protected]>
1 parent 7bfd5c0 commit a71e0f2

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

include/zephyr/posix/pthread.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
429429
int pthread_once(pthread_once_t *once, void (*initFunc)(void));
430430
#endif
431431
FUNC_NORETURN void pthread_exit(void *retval);
432+
int pthread_timedjoin_np(pthread_t thread, void **status, const struct timespec *abstime);
433+
int pthread_tryjoin_np(pthread_t thread, void **status);
432434
int pthread_join(pthread_t thread, void **status);
433435
int pthread_cancel(pthread_t pthread);
434436
int pthread_detach(pthread_t thread);

lib/posix/options/pthread.c

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ BUILD_ASSERT((PTHREAD_CANCEL_ENABLE == 0 || PTHREAD_CANCEL_DISABLE == 0) &&
8181
BUILD_ASSERT(CONFIG_POSIX_PTHREAD_ATTR_STACKSIZE_BITS + CONFIG_POSIX_PTHREAD_ATTR_GUARDSIZE_BITS <=
8282
32);
8383

84+
int64_t timespec_to_timeoutms(const struct timespec *abstime);
8485
static void posix_thread_recycle(void);
8586
static sys_dlist_t posix_thread_q[] = {
8687
SYS_DLIST_STATIC_INIT(&posix_thread_q[POSIX_THREAD_READY_Q]),
@@ -1061,12 +1062,7 @@ void pthread_exit(void *retval)
10611062
CODE_UNREACHABLE;
10621063
}
10631064

1064-
/**
1065-
* @brief Wait for a thread termination.
1066-
*
1067-
* See IEEE 1003.1
1068-
*/
1069-
int pthread_join(pthread_t pthread, void **status)
1065+
static int pthread_timedjoin_internal(pthread_t pthread, void **status, k_timeout_t timeout)
10701066
{
10711067
int ret = ESRCH;
10721068
struct posix_thread *t = NULL;
@@ -1115,8 +1111,19 @@ int pthread_join(pthread_t pthread, void **status)
11151111
break;
11161112
}
11171113

1118-
ret = k_thread_join(&t->thread, K_FOREVER);
1119-
/* other possibilities? */
1114+
ret = k_thread_join(&t->thread, timeout);
1115+
if (ret != 0) {
1116+
/* when joining failed, ensure that the thread can be joined later */
1117+
SYS_SEM_LOCK(&pthread_pool_lock) {
1118+
t->attr.detachstate = PTHREAD_CREATE_JOINABLE;
1119+
}
1120+
}
1121+
if (ret == -EBUSY) {
1122+
return EBUSY;
1123+
} else if (ret == -EAGAIN) {
1124+
return ETIMEDOUT;
1125+
}
1126+
/* Can only be ok or -EDEADLK, which should never occur for pthreads */
11201127
__ASSERT_NO_MSG(ret == 0);
11211128

11221129
LOG_DBG("Joined pthread %p", &t->thread);
@@ -1131,6 +1138,44 @@ int pthread_join(pthread_t pthread, void **status)
11311138
return 0;
11321139
}
11331140

1141+
/**
1142+
* @brief Await a thread termination with timeout.
1143+
*
1144+
* Non-portable GNU extension of IEEE 1003.1
1145+
*/
1146+
int pthread_timedjoin_np(pthread_t pthread, void **status, const struct timespec *abstime)
1147+
{
1148+
if (abstime == NULL) {
1149+
return EINVAL;
1150+
}
1151+
1152+
if (abstime->tv_sec < 0 || abstime->tv_nsec < 0 || abstime->tv_nsec >= NSEC_PER_SEC) {
1153+
return EINVAL;
1154+
}
1155+
1156+
return pthread_timedjoin_internal(pthread, status, K_MSEC(timespec_to_timeoutms(abstime)));
1157+
}
1158+
1159+
/**
1160+
* @brief Check a thread for termination.
1161+
*
1162+
* Non-portable GNU extension of IEEE 1003.1
1163+
*/
1164+
int pthread_tryjoin_np(pthread_t pthread, void **status)
1165+
{
1166+
return pthread_timedjoin_internal(pthread, status, K_NO_WAIT);
1167+
}
1168+
1169+
/**
1170+
* @brief Await a thread termination.
1171+
*
1172+
* See IEEE 1003.1
1173+
*/
1174+
int pthread_join(pthread_t pthread, void **status)
1175+
{
1176+
return pthread_timedjoin_internal(pthread, status, K_FOREVER);
1177+
}
1178+
11341179
/**
11351180
* @brief Detach a thread.
11361181
*

0 commit comments

Comments
 (0)