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 <clamattia@gmail.com>
This commit is contained in:
Cla Galliard 2024-06-01 17:44:41 +02:00 committed by Benjamin Cabé
commit b0baeee03e

View file

@ -143,6 +143,14 @@ static void *thread_top_exec(void *p1)
return NULL;
}
static void *timedjoin_thread(void *p1)
{
int sleep_duration_ms = POINTER_TO_INT(p1);
usleep(USEC_PER_MSEC * sleep_duration_ms);
return NULL;
}
static int bounce_test_done(void)
{
int i;
@ -371,6 +379,69 @@ ZTEST(pthread, test_pthread_termination)
zassert_equal(ret, ESRCH, "cancelled a terminated thread!");
}
ZTEST(pthread, test_pthread_tryjoin)
{
pthread_t th = {0};
int sleep_duration_ms = 200;
void *retval;
/* Creating a thread that exits after 200ms*/
zassert_ok(pthread_create(&th, NULL, timedjoin_thread, INT_TO_POINTER(sleep_duration_ms)));
/* Attempting to join, when thread is still running, should fail */
usleep(USEC_PER_MSEC * sleep_duration_ms / 2);
zassert_equal(pthread_tryjoin_np(th, &retval), EBUSY);
/* Sleep so thread will exit */
usleep(USEC_PER_MSEC * sleep_duration_ms);
/* Attempting to join without blocking should succeed now */
zassert_ok(pthread_tryjoin_np(th, &retval));
}
ZTEST(pthread, test_pthread_timedjoin)
{
pthread_t th = {0};
int sleep_duration_ms = 200;
void *ret;
struct timespec not_done;
struct timespec done;
struct timespec invalid[] = {
[0] = {.tv_sec = -1},
[1] = {.tv_nsec = -1},
[2] = {.tv_nsec = NSEC_PER_SEC},
};
/* setup timespecs when the thread is still running and when it is done */
clock_gettime(CLOCK_MONOTONIC, &not_done);
clock_gettime(CLOCK_MONOTONIC, &done);
not_done.tv_nsec += sleep_duration_ms / 2 * NSEC_PER_MSEC;
done.tv_nsec += sleep_duration_ms * 1.5 * NSEC_PER_MSEC;
while (not_done.tv_nsec >= NSEC_PER_SEC) {
not_done.tv_sec++;
not_done.tv_nsec -= NSEC_PER_SEC;
}
while (done.tv_nsec >= NSEC_PER_SEC) {
done.tv_sec++;
done.tv_nsec -= NSEC_PER_SEC;
}
/* Creating a thread that exits after 200ms*/
zassert_ok(pthread_create(&th, NULL, timedjoin_thread, INT_TO_POINTER(sleep_duration_ms)));
/* pthread_timedjoin-np must return -EINVAL for invalid struct timespecs */
zassert_equal(pthread_timedjoin_np(th, &ret, NULL), EINVAL);
for (size_t i = 0; i < ARRAY_SIZE(invalid); ++i) {
zassert_equal(pthread_timedjoin_np(th, &ret, &invalid[i]), EINVAL);
}
/* Attempting to join with a timeout, when the thread is still running should fail */
zassert_equal(pthread_timedjoin_np(th, &ret, &not_done), ETIMEDOUT);
/* Attempting to join with a timeout, when the thread is done, should succeed */
zassert_ok(pthread_timedjoin_np(th, &ret, &done));
}
static void *create_thread1(void *p1)
{
/* do nothing */