Skip to content

Commit b0baeee

Browse files
ClaCodeskartben
authored andcommitted
tests/posix: Add test for pthread_timed_join and pthread_try_join
Test for the non-standard but useful pthread_timed_join- and pthread_try_join-functions. Signed-off-by: Cla Galliard <[email protected]>
1 parent a71e0f2 commit b0baeee

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

tests/posix/common/src/pthread.c

+71
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ static void *thread_top_exec(void *p1)
143143
return NULL;
144144
}
145145

146+
static void *timedjoin_thread(void *p1)
147+
{
148+
int sleep_duration_ms = POINTER_TO_INT(p1);
149+
150+
usleep(USEC_PER_MSEC * sleep_duration_ms);
151+
return NULL;
152+
}
153+
146154
static int bounce_test_done(void)
147155
{
148156
int i;
@@ -371,6 +379,69 @@ ZTEST(pthread, test_pthread_termination)
371379
zassert_equal(ret, ESRCH, "cancelled a terminated thread!");
372380
}
373381

382+
ZTEST(pthread, test_pthread_tryjoin)
383+
{
384+
pthread_t th = {0};
385+
int sleep_duration_ms = 200;
386+
void *retval;
387+
388+
/* Creating a thread that exits after 200ms*/
389+
zassert_ok(pthread_create(&th, NULL, timedjoin_thread, INT_TO_POINTER(sleep_duration_ms)));
390+
391+
/* Attempting to join, when thread is still running, should fail */
392+
usleep(USEC_PER_MSEC * sleep_duration_ms / 2);
393+
zassert_equal(pthread_tryjoin_np(th, &retval), EBUSY);
394+
395+
/* Sleep so thread will exit */
396+
usleep(USEC_PER_MSEC * sleep_duration_ms);
397+
398+
/* Attempting to join without blocking should succeed now */
399+
zassert_ok(pthread_tryjoin_np(th, &retval));
400+
}
401+
402+
ZTEST(pthread, test_pthread_timedjoin)
403+
{
404+
pthread_t th = {0};
405+
int sleep_duration_ms = 200;
406+
void *ret;
407+
struct timespec not_done;
408+
struct timespec done;
409+
struct timespec invalid[] = {
410+
[0] = {.tv_sec = -1},
411+
[1] = {.tv_nsec = -1},
412+
[2] = {.tv_nsec = NSEC_PER_SEC},
413+
};
414+
415+
/* setup timespecs when the thread is still running and when it is done */
416+
clock_gettime(CLOCK_MONOTONIC, &not_done);
417+
clock_gettime(CLOCK_MONOTONIC, &done);
418+
not_done.tv_nsec += sleep_duration_ms / 2 * NSEC_PER_MSEC;
419+
done.tv_nsec += sleep_duration_ms * 1.5 * NSEC_PER_MSEC;
420+
while (not_done.tv_nsec >= NSEC_PER_SEC) {
421+
not_done.tv_sec++;
422+
not_done.tv_nsec -= NSEC_PER_SEC;
423+
}
424+
while (done.tv_nsec >= NSEC_PER_SEC) {
425+
done.tv_sec++;
426+
done.tv_nsec -= NSEC_PER_SEC;
427+
}
428+
429+
/* Creating a thread that exits after 200ms*/
430+
zassert_ok(pthread_create(&th, NULL, timedjoin_thread, INT_TO_POINTER(sleep_duration_ms)));
431+
432+
/* pthread_timedjoin-np must return -EINVAL for invalid struct timespecs */
433+
zassert_equal(pthread_timedjoin_np(th, &ret, NULL), EINVAL);
434+
for (size_t i = 0; i < ARRAY_SIZE(invalid); ++i) {
435+
zassert_equal(pthread_timedjoin_np(th, &ret, &invalid[i]), EINVAL);
436+
}
437+
438+
/* Attempting to join with a timeout, when the thread is still running should fail */
439+
zassert_equal(pthread_timedjoin_np(th, &ret, &not_done), ETIMEDOUT);
440+
441+
/* Attempting to join with a timeout, when the thread is done, should succeed */
442+
zassert_ok(pthread_timedjoin_np(th, &ret, &done));
443+
}
444+
374445
static void *create_thread1(void *p1)
375446
{
376447
/* do nothing */

0 commit comments

Comments
 (0)