@@ -143,6 +143,14 @@ static void *thread_top_exec(void *p1)
143
143
return NULL ;
144
144
}
145
145
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
+
146
154
static int bounce_test_done (void )
147
155
{
148
156
int i ;
@@ -371,6 +379,69 @@ ZTEST(pthread, test_pthread_termination)
371
379
zassert_equal (ret , ESRCH , "cancelled a terminated thread!" );
372
380
}
373
381
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
+
374
445
static void * create_thread1 (void * p1 )
375
446
{
376
447
/* do nothing */
0 commit comments