@@ -64,6 +64,8 @@ enum posix_thread_qid {
6464 POSIX_THREAD_RUN_Q ,
6565 /* exited (either joinable or detached) */
6666 POSIX_THREAD_DONE_Q ,
67+ /* invalid */
68+ POSIX_THREAD_INVALID_Q ,
6769};
6870
6971/* only 2 bits in struct posix_thread_attr for schedpolicy */
@@ -79,13 +81,43 @@ BUILD_ASSERT(CONFIG_POSIX_PTHREAD_ATTR_STACKSIZE_BITS + CONFIG_POSIX_PTHREAD_ATT
7981 32 );
8082
8183static void posix_thread_recycle (void );
82- static sys_dlist_t ready_q = SYS_DLIST_STATIC_INIT (& ready_q );
83- static sys_dlist_t run_q = SYS_DLIST_STATIC_INIT (& run_q );
84- static sys_dlist_t done_q = SYS_DLIST_STATIC_INIT (& done_q );
84+ static sys_dlist_t posix_thread_q [] = {
85+ SYS_DLIST_STATIC_INIT (& posix_thread_q [POSIX_THREAD_READY_Q ]),
86+ SYS_DLIST_STATIC_INIT (& posix_thread_q [POSIX_THREAD_RUN_Q ]),
87+ SYS_DLIST_STATIC_INIT (& posix_thread_q [POSIX_THREAD_DONE_Q ]),
88+ };
8589static struct posix_thread posix_thread_pool [CONFIG_MAX_PTHREAD_COUNT ];
8690static struct k_spinlock pthread_pool_lock ;
8791static int pthread_concurrency ;
8892
93+ static inline void posix_thread_q_set (struct posix_thread * t , enum posix_thread_qid qid )
94+ {
95+ switch (qid ) {
96+ case POSIX_THREAD_READY_Q :
97+ case POSIX_THREAD_RUN_Q :
98+ case POSIX_THREAD_DONE_Q :
99+ sys_dlist_append (& posix_thread_q [qid ], & t -> q_node );
100+ t -> qid = qid ;
101+ break ;
102+ default :
103+ __ASSERT (false, "cannot set invalid qid %d for posix thread %p" , qid , t );
104+ break ;
105+ }
106+ }
107+
108+ static inline enum posix_thread_qid posix_thread_q_get (struct posix_thread * t )
109+ {
110+ switch (t -> qid ) {
111+ case POSIX_THREAD_READY_Q :
112+ case POSIX_THREAD_RUN_Q :
113+ case POSIX_THREAD_DONE_Q :
114+ return t -> qid ;
115+ default :
116+ __ASSERT (false, "posix thread %p has invalid qid: %d" , t , t -> qid );
117+ return POSIX_THREAD_INVALID_Q ;
118+ }
119+ }
120+
89121/*
90122 * We reserve the MSB to mark a pthread_t as initialized (from the
91123 * perspective of the application). With a linear space, this means that
@@ -128,9 +160,9 @@ struct posix_thread *to_posix_thread(pthread_t pthread)
128160 * This differs from other posix object allocation strategies because they use
129161 * a bitarray to indicate whether an object has been allocated.
130162 */
131- actually_initialized = !(
132- t -> qid == POSIX_THREAD_READY_Q ||
133- ( t -> qid == POSIX_THREAD_DONE_Q && t -> attr .detachstate == PTHREAD_CREATE_DETACHED ));
163+ actually_initialized = !(posix_thread_q_get ( t ) == POSIX_THREAD_READY_Q ||
164+ ( posix_thread_q_get ( t ) == POSIX_THREAD_DONE_Q &&
165+ t -> attr .detachstate == PTHREAD_CREATE_DETACHED ));
134166
135167 if (!actually_initialized ) {
136168 LOG_ERR ("Pthread claims to be initialized (%x)" , pthread );
@@ -379,8 +411,7 @@ static void posix_thread_finalize(struct posix_thread *t, void *retval)
379411 /* move thread from run_q to done_q */
380412 key = k_spin_lock (& pthread_pool_lock );
381413 sys_dlist_remove (& t -> q_node );
382- sys_dlist_append (& done_q , & t -> q_node );
383- t -> qid = POSIX_THREAD_DONE_Q ;
414+ posix_thread_q_set (t , POSIX_THREAD_DONE_Q );
384415 t -> retval = retval ;
385416 k_spin_unlock (& pthread_pool_lock , key );
386417
@@ -419,7 +450,7 @@ static void posix_thread_recycle(void)
419450 sys_dlist_t recyclables = SYS_DLIST_STATIC_INIT (& recyclables );
420451
421452 key = k_spin_lock (& pthread_pool_lock );
422- SYS_DLIST_FOR_EACH_CONTAINER_SAFE (& done_q , t , safe_t , q_node ) {
453+ SYS_DLIST_FOR_EACH_CONTAINER_SAFE (& posix_thread_q [ POSIX_THREAD_DONE_Q ] , t , safe_t , q_node ) {
423454 if (t -> attr .detachstate == PTHREAD_CREATE_JOINABLE ) {
424455 /* thread has not been joined yet */
425456 continue ;
@@ -447,8 +478,7 @@ static void posix_thread_recycle(void)
447478 key = k_spin_lock (& pthread_pool_lock );
448479 while (!sys_dlist_is_empty (& recyclables )) {
449480 t = CONTAINER_OF (sys_dlist_get (& recyclables ), struct posix_thread , q_node );
450- t -> qid = POSIX_THREAD_READY_Q ;
451- sys_dlist_append (& ready_q , & t -> q_node );
481+ posix_thread_q_set (t , POSIX_THREAD_READY_Q );
452482 }
453483 k_spin_unlock (& pthread_pool_lock , key );
454484}
@@ -476,12 +506,12 @@ int pthread_create(pthread_t *th, const pthread_attr_t *_attr, void *(*threadrou
476506 posix_thread_recycle ();
477507
478508 K_SPINLOCK (& pthread_pool_lock ) {
479- if (!sys_dlist_is_empty (& ready_q )) {
480- t = CONTAINER_OF (sys_dlist_get (& ready_q ), struct posix_thread , q_node );
509+ if (!sys_dlist_is_empty (& posix_thread_q [POSIX_THREAD_READY_Q ])) {
510+ t = CONTAINER_OF (sys_dlist_get (& posix_thread_q [POSIX_THREAD_READY_Q ]),
511+ struct posix_thread , q_node );
481512
482513 /* initialize thread state */
483- sys_dlist_append (& run_q , & t -> q_node );
484- t -> qid = POSIX_THREAD_RUN_Q ;
514+ posix_thread_q_set (t , POSIX_THREAD_RUN_Q );
485515 sys_slist_init (& t -> key_list );
486516 sys_slist_init (& t -> cleanup_list );
487517 }
@@ -493,8 +523,7 @@ int pthread_create(pthread_t *th, const pthread_attr_t *_attr, void *(*threadrou
493523 /* cannot allocate barrier. move thread back to ready_q */
494524 K_SPINLOCK (& pthread_pool_lock ) {
495525 sys_dlist_remove (& t -> q_node );
496- sys_dlist_append (& ready_q , & t -> q_node );
497- t -> qid = POSIX_THREAD_READY_Q ;
526+ posix_thread_q_set (t , POSIX_THREAD_READY_Q );
498527 }
499528 t = NULL ;
500529 }
@@ -516,8 +545,7 @@ int pthread_create(pthread_t *th, const pthread_attr_t *_attr, void *(*threadrou
516545 /* cannot allocate pthread attributes (e.g. stack) */
517546 K_SPINLOCK (& pthread_pool_lock ) {
518547 sys_dlist_remove (& t -> q_node );
519- sys_dlist_append (& ready_q , & t -> q_node );
520- t -> qid = POSIX_THREAD_READY_Q ;
548+ posix_thread_q_set (t , POSIX_THREAD_READY_Q );
521549 }
522550 return err ;
523551 }
@@ -886,7 +914,7 @@ int pthread_join(pthread_t pthread, void **status)
886914 K_SPINLOCK_BREAK ;
887915 }
888916
889- if (t -> qid == POSIX_THREAD_READY_Q ) {
917+ if (posix_thread_q_get ( t ) == POSIX_THREAD_READY_Q ) {
890918 ret = ESRCH ;
891919 K_SPINLOCK_BREAK ;
892920 }
@@ -942,7 +970,7 @@ int pthread_detach(pthread_t pthread)
942970 K_SPINLOCK_BREAK ;
943971 }
944972
945- if (t -> qid == POSIX_THREAD_READY_Q ||
973+ if (posix_thread_q_get ( t ) == POSIX_THREAD_READY_Q ||
946974 t -> attr .detachstate != PTHREAD_CREATE_JOINABLE ) {
947975 LOG_ERR ("Pthread %p cannot be detached" , & t -> thread );
948976 ret = EINVAL ;
@@ -1288,7 +1316,7 @@ static int posix_thread_pool_init(void)
12881316 size_t i ;
12891317
12901318 for (i = 0 ; i < CONFIG_MAX_PTHREAD_COUNT ; ++ i ) {
1291- sys_dlist_append ( & ready_q , & posix_thread_pool [i ]. q_node );
1319+ posix_thread_q_set ( & posix_thread_pool [i ], POSIX_THREAD_READY_Q );
12921320 }
12931321
12941322 return 0 ;
0 commit comments