@@ -52,9 +52,13 @@ static inline u32_t cmsis_to_zephyr_priority(u32_t c_prio)
52
52
53
53
static void zephyr_thread_wrapper (void * arg1 , void * arg2 , void * arg3 )
54
54
{
55
+ struct cv2_thread * tid = arg2 ;
55
56
void * (* fun_ptr )(void * ) = arg3 ;
56
57
57
58
fun_ptr (arg1 );
59
+
60
+ tid -> has_joined = TRUE;
61
+ k_sem_give (& tid -> join_guard );
58
62
}
59
63
60
64
void * is_cmsis_rtos_v2_thread (void * thread_id )
@@ -157,7 +161,7 @@ osThreadId_t osThreadNew(osThreadFunc_t threadfunc, void *arg,
157
161
this_thread_num = atomic_inc ((atomic_t * )& thread_num );
158
162
159
163
tid = & cv2_thread_pool [this_thread_num ];
160
- tid -> state = attr -> attr_bits ;
164
+ tid -> attr_bits = attr -> attr_bits ;
161
165
162
166
if (attr -> stack_mem == NULL ) {
163
167
__ASSERT (CONFIG_CMSIS_V2_THREAD_DYNAMIC_STACK_SIZE > 0 ,
@@ -184,13 +188,15 @@ osThreadId_t osThreadNew(osThreadFunc_t threadfunc, void *arg,
184
188
185
189
sys_dlist_append (& thread_list , & tid -> node );
186
190
191
+ k_sem_init (& tid -> join_guard , 0 , 1 );
192
+ tid -> has_joined = FALSE;
193
+
187
194
(void )k_thread_create (& tid -> z_thread ,
188
195
stack , stack_size ,
189
196
(k_thread_entry_t )zephyr_thread_wrapper ,
190
- (void * )arg , NULL , threadfunc ,
197
+ (void * )arg , tid , threadfunc ,
191
198
prio , 0 , K_NO_WAIT );
192
199
193
-
194
200
if (attr -> name == NULL ) {
195
201
strncpy (tid -> name , init_thread_attrs .name ,
196
202
sizeof (tid -> name ) - 1 );
@@ -417,6 +423,77 @@ osStatus_t osThreadResume(osThreadId_t thread_id)
417
423
return osOK ;
418
424
}
419
425
426
+ /**
427
+ * @brief Detach a thread (thread storage can be reclaimed when thread
428
+ * terminates).
429
+ */
430
+ osStatus_t osThreadDetach (osThreadId_t thread_id )
431
+ {
432
+ struct cv2_thread * tid = (struct cv2_thread * )thread_id ;
433
+
434
+ if ((tid == NULL ) || (is_cmsis_rtos_v2_thread (tid ) == NULL )) {
435
+ return osErrorParameter ;
436
+ }
437
+
438
+ if (k_is_in_isr ()) {
439
+ return osErrorISR ;
440
+ }
441
+
442
+ if (_is_thread_cmsis_inactive (& tid -> z_thread )) {
443
+ return osErrorResource ;
444
+ }
445
+
446
+ __ASSERT (tid -> attr_bits != osThreadDetached ,
447
+ "Thread already detached, behaviour undefined." );
448
+
449
+ tid -> attr_bits = osThreadDetached ;
450
+
451
+ k_sem_give (& tid -> join_guard );
452
+
453
+ return osOK ;
454
+ }
455
+
456
+ /**
457
+ * @brief Wait for specified thread to terminate.
458
+ */
459
+ osStatus_t osThreadJoin (osThreadId_t thread_id )
460
+ {
461
+ struct cv2_thread * tid = (struct cv2_thread * )thread_id ;
462
+ osStatus_t status = osError ;
463
+
464
+ if ((tid == NULL ) || (is_cmsis_rtos_v2_thread (tid ) == NULL )) {
465
+ return osErrorParameter ;
466
+ }
467
+
468
+ if (k_is_in_isr ()) {
469
+ return osErrorISR ;
470
+ }
471
+
472
+ if (_is_thread_cmsis_inactive (& tid -> z_thread )) {
473
+ return osErrorResource ;
474
+ }
475
+
476
+ if (tid -> attr_bits != osThreadJoinable ) {
477
+ return osErrorResource ;
478
+ }
479
+
480
+ if (!tid -> has_joined ) {
481
+ if (k_sem_take (& tid -> join_guard , K_FOREVER ) != 0 ) {
482
+ __ASSERT (0 , "Failed to take from join guard." );
483
+ }
484
+
485
+ k_sem_give (& tid -> join_guard );
486
+ }
487
+
488
+ if (tid -> has_joined && (tid -> attr_bits == osThreadJoinable )) {
489
+ status = osOK ;
490
+ } else {
491
+ status = osErrorResource ;
492
+ }
493
+
494
+ return status ;
495
+ }
496
+
420
497
/**
421
498
* @brief Terminate execution of current running thread.
422
499
*/
@@ -427,6 +504,8 @@ __NO_RETURN void osThreadExit(void)
427
504
__ASSERT (!k_is_in_isr (), "" );
428
505
tid = osThreadGetId ();
429
506
507
+ k_sem_give (& tid -> join_guard );
508
+
430
509
k_thread_abort ((k_tid_t )& tid -> z_thread );
431
510
432
511
CODE_UNREACHABLE ;
@@ -451,6 +530,8 @@ osStatus_t osThreadTerminate(osThreadId_t thread_id)
451
530
return osErrorResource ;
452
531
}
453
532
533
+ k_sem_give (& tid -> join_guard );
534
+
454
535
k_thread_abort ((k_tid_t )& tid -> z_thread );
455
536
return osOK ;
456
537
}
0 commit comments