RTEMS  5.0.0
threadqimpl.h
Go to the documentation of this file.
1 
10 /*
11  * COPYRIGHT (c) 1989-2014.
12  * On-Line Applications Research Corporation (OAR).
13  *
14  * The license and distribution terms for this file may be
15  * found in the file LICENSE in this distribution or at
16  * http://www.rtems.org/license/LICENSE.
17  */
18 
19 #ifndef _RTEMS_SCORE_THREADQIMPL_H
20 #define _RTEMS_SCORE_THREADQIMPL_H
21 
22 #include <rtems/score/threadq.h>
23 #include <rtems/score/chainimpl.h>
24 #include <rtems/score/priorityimpl.h>
25 #include <rtems/score/scheduler.h>
26 #include <rtems/score/smp.h>
27 #include <rtems/score/status.h>
28 #include <rtems/score/thread.h>
29 #include <rtems/score/threaddispatch.h>
30 
31 #if defined(RTEMS_DEBUG)
32 #include <string.h>
33 #endif
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
44 #define THREAD_QUEUE_LINK_OF_PATH_NODE( node ) \
45  RTEMS_CONTAINER_OF( node, Thread_queue_Link, Path_node );
46 
51 typedef struct {
52 #if !defined(RTEMS_SMP)
53  /*
54  * The struct _Thread_queue_Queue definition is independent of the RTEMS
55  * build configuration. Thus, the storage space for the SMP lock is always
56  * present. In SMP configurations, the SMP lock is contained in the
57  * Thread_queue_Queue.
58  */
59  unsigned int reserved[2];
60 #endif
61 
62  Thread_queue_Queue Queue;
64 
65 void _Thread_queue_Enqueue_do_nothing_extra(
66  Thread_queue_Queue *queue,
67  Thread_Control *the_thread,
68  Per_CPU_Control *cpu_self,
69  Thread_queue_Context *queue_context
70 );
71 
72 void _Thread_queue_Add_timeout_ticks(
73  Thread_queue_Queue *queue,
74  Thread_Control *the_thread,
75  Per_CPU_Control *cpu_self,
76  Thread_queue_Context *queue_context
77 );
78 
79 void _Thread_queue_Add_timeout_monotonic_timespec(
80  Thread_queue_Queue *queue,
81  Thread_Control *the_thread,
82  Per_CPU_Control *cpu_self,
83  Thread_queue_Context *queue_context
84 );
85 
86 void _Thread_queue_Add_timeout_realtime_timespec(
87  Thread_queue_Queue *queue,
88  Thread_Control *the_thread,
89  Per_CPU_Control *cpu_self,
90  Thread_queue_Context *queue_context
91 );
92 
97 
101 void _Thread_queue_Deadlock_fatal( Thread_Control *the_thread );
102 
109  Thread_queue_Context *queue_context
110 )
111 {
112 #if defined(RTEMS_DEBUG)
113  memset( queue_context, 0x7f, sizeof( *queue_context ) );
114 #if defined(RTEMS_SMP)
115  _Chain_Initialize_node( &queue_context->Lock_context.Wait.Gate.Node );
116 #endif
117  queue_context->enqueue_callout = NULL;
118  queue_context->deadlock_callout = NULL;
119 #else
120  (void) queue_context;
121 #endif
122 }
123 
135  Thread_queue_Context *queue_context,
136  States_Control thread_state
137 )
138 {
139  queue_context->thread_state = thread_state;
140 }
141 
152  Thread_queue_Context *queue_context,
153  Watchdog_Interval ticks
154 )
155 {
156  queue_context->Timeout.ticks = ticks;
157 }
158 
169  Thread_queue_Context *queue_context,
170  const void *arg
171 )
172 {
173  queue_context->Timeout.arg = arg;
174 }
175 
186  Thread_queue_Context *queue_context,
187  Thread_queue_Enqueue_callout enqueue_callout
188 )
189 {
190  queue_context->enqueue_callout = enqueue_callout;
191 }
192 
202  Thread_queue_Context *queue_context
203 )
204 {
205  queue_context->enqueue_callout = _Thread_queue_Enqueue_do_nothing_extra;
206 }
207 
219  Thread_queue_Context *queue_context,
220  Watchdog_Interval ticks
221 )
222 {
223  queue_context->Timeout.ticks = ticks;
224  queue_context->enqueue_callout = _Thread_queue_Add_timeout_ticks;
225 }
226 
238  Thread_queue_Context *queue_context,
239  const struct timespec *abstime
240 )
241 {
242  queue_context->Timeout.arg = abstime;
243  queue_context->enqueue_callout =
244  _Thread_queue_Add_timeout_monotonic_timespec;
245 }
246 
258  Thread_queue_Context *queue_context,
259  const struct timespec *abstime
260 )
261 {
262  queue_context->Timeout.arg = abstime;
263  queue_context->enqueue_callout = _Thread_queue_Add_timeout_realtime_timespec;
264 }
265 
281  Thread_queue_Context *queue_context,
282  Thread_queue_Deadlock_callout deadlock_callout
283 )
284 {
285  queue_context->deadlock_callout = deadlock_callout;
286 }
287 
288 RTEMS_INLINE_ROUTINE void _Thread_queue_Context_clear_priority_updates(
289  Thread_queue_Context *queue_context
290 )
291 {
292  queue_context->Priority.update_count = 0;
293 }
294 
295 RTEMS_INLINE_ROUTINE size_t _Thread_queue_Context_save_priority_updates(
296  Thread_queue_Context *queue_context
297 )
298 {
299  return queue_context->Priority.update_count;
300 }
301 
302 RTEMS_INLINE_ROUTINE void _Thread_queue_Context_restore_priority_updates(
303  Thread_queue_Context *queue_context,
304  size_t update_count
305 )
306 {
307  queue_context->Priority.update_count = update_count;
308 }
309 
310 RTEMS_INLINE_ROUTINE void _Thread_queue_Context_add_priority_update(
311  Thread_queue_Context *queue_context,
312  Thread_Control *the_thread
313 )
314 {
315  size_t n;
316 
317  n = queue_context->Priority.update_count;
318  _Assert( n < RTEMS_ARRAY_SIZE( queue_context->Priority.update ) );
319 
320  queue_context->Priority.update_count = n + 1;
321  queue_context->Priority.update[ n ] = the_thread;
322 }
323 
324 #define _Thread_queue_Context_ISR_disable( queue_context, level ) \
325  do { \
326  _ISR_Local_disable( level ); \
327  _ISR_lock_ISR_disable_profile( \
328  &( queue_context )->Lock_context.Lock_context \
329  ) \
330  } while ( 0 )
331 
332 RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_ISR_level(
333  Thread_queue_Context *queue_context,
334  ISR_Level level
335 )
336 {
338  &queue_context->Lock_context.Lock_context,
339  level
340  );
341 }
342 
343 RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_queue_Dispatch_disable(
344  Thread_queue_Context *queue_context
345 )
346 {
348  &queue_context->Lock_context.Lock_context
349  );
350 }
351 
361 #if defined(RTEMS_MULTIPROCESSING)
363  Thread_queue_Context *queue_context,
364  Thread_queue_MP_callout mp_callout
365 )
366 {
367  queue_context->mp_callout = mp_callout;
368 }
369 #else
370 #define _Thread_queue_Context_set_MP_callout( queue_context, mp_callout ) \
371  do { \
372  (void) queue_context; \
373  } while ( 0 )
374 #endif
375 
376 #if defined(RTEMS_SMP)
377 RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_close(
378  Thread_queue_Gate *gate
379 )
380 {
381  _Atomic_Store_uint( &gate->go_ahead, 0, ATOMIC_ORDER_RELAXED );
382 }
383 
384 RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_add(
385  Chain_Control *chain,
386  Thread_queue_Gate *gate
387 )
388 {
389  _Chain_Append_unprotected( chain, &gate->Node );
390 }
391 
392 RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_open(
393  Thread_queue_Gate *gate
394 )
395 {
396  _Atomic_Store_uint( &gate->go_ahead, 1, ATOMIC_ORDER_RELAXED );
397 }
398 
399 RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_wait(
400  Thread_queue_Gate *gate
401 )
402 {
403  while ( _Atomic_Load_uint( &gate->go_ahead, ATOMIC_ORDER_RELAXED ) == 0 ) {
404  /* Wait */
405  }
406 }
407 #endif
408 
409 RTEMS_INLINE_ROUTINE void _Thread_queue_Heads_initialize(
410  Thread_queue_Heads *heads
411 )
412 {
413 #if defined(RTEMS_SMP)
414  size_t i;
415 
416  for ( i = 0; i < _Scheduler_Count; ++i ) {
417  _Chain_Initialize_node( &heads->Priority[ i ].Node );
418  _Priority_Initialize_empty( &heads->Priority[ i ].Queue );
419  heads->Priority[ i ].Queue.scheduler = &_Scheduler_Table[ i ];
420  }
421 #endif
422 
425 }
426 
427 RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_initialize(
428  Thread_queue_Queue *queue,
429  const char *name
430 )
431 {
432 #if defined(RTEMS_SMP)
433  _SMP_ticket_lock_Initialize( &queue->Lock );
434 #endif
435  queue->heads = NULL;
436  queue->owner = NULL;
437  queue->name = name;
438 }
439 
440 RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_do_acquire_critical(
441  Thread_queue_Queue *queue,
442 #if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
443  SMP_lock_Stats *lock_stats,
444 #endif
445  ISR_lock_Context *lock_context
446 )
447 {
448 #if defined(RTEMS_SMP)
449  _SMP_ticket_lock_Acquire(
450  &queue->Lock,
451  lock_stats,
452  &lock_context->Lock_context.Stats_context
453  );
454 #else
455  (void) queue;
456  (void) lock_context;
457 #endif
458 }
459 
460 #if defined(RTEMS_SMP) && defined( RTEMS_PROFILING )
461  #define \
462  _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \
463  _Thread_queue_Queue_do_acquire_critical( queue, lock_stats, lock_context )
464 #else
465  #define \
466  _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \
467  _Thread_queue_Queue_do_acquire_critical( queue, lock_context )
468 #endif
469 
470 RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release_critical(
471  Thread_queue_Queue *queue,
472  ISR_lock_Context *lock_context
473 )
474 {
475 #if defined(RTEMS_SMP)
476  _SMP_ticket_lock_Release(
477  &queue->Lock,
478  &lock_context->Lock_context.Stats_context
479  );
480 #else
481  (void) queue;
482  (void) lock_context;
483 #endif
484 }
485 
486 RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release(
487  Thread_queue_Queue *queue,
488  ISR_lock_Context *lock_context
489 )
490 {
491  _Thread_queue_Queue_release_critical( queue, lock_context );
492  _ISR_lock_ISR_enable( lock_context );
493 }
494 
508  const Thread_queue_Queue *queue,
509  char *buffer,
510  size_t buffer_size,
511  Objects_Id *id
512 );
513 
514 #if defined(RTEMS_SMP)
515 void _Thread_queue_Do_acquire_critical(
516  Thread_queue_Control *the_thread_queue,
517  ISR_lock_Context *lock_context
518 );
519 #else
520 RTEMS_INLINE_ROUTINE void _Thread_queue_Do_acquire_critical(
521  Thread_queue_Control *the_thread_queue,
522  ISR_lock_Context *lock_context
523 )
524 {
525  (void) the_thread_queue;
526  (void) lock_context;
527 }
528 #endif
529 
530 RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical(
531  Thread_queue_Control *the_thread_queue,
532  Thread_queue_Context *queue_context
533 )
534 {
535  _Thread_queue_Do_acquire_critical(
536  the_thread_queue,
537  &queue_context->Lock_context.Lock_context
538  );
539 }
540 
541 #if defined(RTEMS_SMP)
542 void _Thread_queue_Acquire(
543  Thread_queue_Control *the_thread_queue,
544  Thread_queue_Context *queue_context
545 );
546 #else
547 RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire(
548  Thread_queue_Control *the_thread_queue,
549  Thread_queue_Context *queue_context
550 )
551 {
552  (void) the_thread_queue;
554 }
555 #endif
556 
557 #if defined(RTEMS_DEBUG)
558 RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_lock_owner(
559  const Thread_queue_Control *the_thread_queue
560 )
561 {
562 #if defined(RTEMS_SMP)
563  return the_thread_queue->owner == _SMP_lock_Who_am_I();
564 #else
565  return _ISR_Get_level() != 0;
566 #endif
567 }
568 #endif
569 
570 #if defined(RTEMS_SMP)
571 void _Thread_queue_Do_release_critical(
572  Thread_queue_Control *the_thread_queue,
573  ISR_lock_Context *lock_context
574 );
575 #else
576 RTEMS_INLINE_ROUTINE void _Thread_queue_Do_release_critical(
577  Thread_queue_Control *the_thread_queue,
578  ISR_lock_Context *lock_context
579 )
580 {
581  (void) the_thread_queue;
582  (void) lock_context;
583  _Assert( _Thread_queue_Is_lock_owner( the_thread_queue ) );
584 }
585 #endif
586 
587 RTEMS_INLINE_ROUTINE void _Thread_queue_Release_critical(
588  Thread_queue_Control *the_thread_queue,
589  Thread_queue_Context *queue_context
590 )
591 {
592  _Thread_queue_Do_release_critical(
593  the_thread_queue,
594  &queue_context->Lock_context.Lock_context
595  );
596 }
597 
598 #if defined(RTEMS_SMP)
599 void _Thread_queue_Release(
600  Thread_queue_Control *the_thread_queue,
601  Thread_queue_Context *queue_context
602 );
603 #else
604 RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
605  Thread_queue_Control *the_thread_queue,
606  Thread_queue_Context *queue_context
607 )
608 {
609  (void) the_thread_queue;
610  _Assert( _Thread_queue_Is_lock_owner( the_thread_queue ) );
612 }
613 #endif
614 
615 Thread_Control *_Thread_queue_Do_dequeue(
616  Thread_queue_Control *the_thread_queue,
617  const Thread_queue_Operations *operations
618 #if defined(RTEMS_MULTIPROCESSING)
619  ,
620  Thread_queue_MP_callout mp_callout
621 #endif
622 );
623 
635 #if defined(RTEMS_MULTIPROCESSING)
636  #define _Thread_queue_Dequeue( \
637  the_thread_queue, \
638  operations, \
639  mp_callout \
640  ) \
641  _Thread_queue_Do_dequeue( \
642  the_thread_queue, \
643  operations, \
644  mp_callout \
645  )
646 #else
647  #define _Thread_queue_Dequeue( \
648  the_thread_queue, \
649  operations, \
650  mp_callout \
651  ) \
652  _Thread_queue_Do_dequeue( \
653  the_thread_queue, \
654  operations \
655  )
656 #endif
657 
736  Thread_queue_Queue *queue,
737  const Thread_queue_Operations *operations,
738  Thread_Control *the_thread,
739  Thread_queue_Context *queue_context
740 );
741 
742 #if defined(RTEMS_SMP)
743 
765 Status_Control _Thread_queue_Enqueue_sticky(
766  Thread_queue_Queue *queue,
767  const Thread_queue_Operations *operations,
768  Thread_Control *the_thread,
769  Thread_queue_Context *queue_context
770 );
771 #endif
772 
794  Thread_queue_Queue *queue,
795  const Thread_queue_Operations *operations,
796  Thread_Control *the_thread,
797  Thread_queue_Context *queue_context
798 );
799 
815  bool unblock,
816  Thread_queue_Queue *queue,
817  Thread_Control *the_thread,
818  ISR_lock_Context *lock_context
819 );
820 
868  Thread_queue_Queue *queue,
869  const Thread_queue_Operations *operations,
870  Thread_Control *the_thread,
871  Thread_queue_Context *queue_context
872 );
873 
883 void _Thread_queue_Extract( Thread_Control *the_thread );
884 
893  Thread_Control *the_thread
894 );
895 
913  Thread_queue_Queue *queue,
914  Thread_queue_Heads *heads,
915  Thread_Control *previous_owner,
916  Thread_queue_Context *queue_context,
917  const Thread_queue_Operations *operations
918 );
919 
920 #if defined(RTEMS_SMP)
921 
941 void _Thread_queue_Surrender_sticky(
942  Thread_queue_Queue *queue,
943  Thread_queue_Heads *heads,
944  Thread_Control *previous_owner,
945  Thread_queue_Context *queue_context,
946  const Thread_queue_Operations *operations
947 );
948 #endif
949 
950 RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_empty(
951  const Thread_queue_Queue *queue
952 )
953 {
954  return queue->heads == NULL;
955 }
956 
972  Thread_queue_Control *the_thread_queue,
973  const Thread_queue_Operations *operations
974 )
975 {
976  Thread_queue_Heads *heads = the_thread_queue->Queue.heads;
977 
978  if ( heads != NULL ) {
979  return ( *operations->first )( heads );
980  } else {
981  return NULL;
982  }
983 }
984 
996  Thread_queue_Control *the_thread_queue,
997  const Thread_queue_Operations *operations
998 );
999 
1021 typedef Thread_Control *( *Thread_queue_Flush_filter )(
1022  Thread_Control *the_thread,
1023  Thread_queue_Queue *queue,
1024  Thread_queue_Context *queue_context
1025 );
1026 
1037  Thread_Control *the_thread,
1038  Thread_queue_Queue *queue,
1039  Thread_queue_Context *queue_context
1040 );
1041 
1054  Thread_Control *the_thread,
1055  Thread_queue_Queue *queue,
1056  Thread_queue_Context *queue_context
1057 );
1058 
1071  Thread_Control *the_thread,
1072  Thread_queue_Queue *queue,
1073  Thread_queue_Context *queue_context
1074 );
1075 
1099  Thread_queue_Queue *queue,
1100  const Thread_queue_Operations *operations,
1102  Thread_queue_Context *queue_context
1103 );
1104 
1105 void _Thread_queue_Initialize(
1106  Thread_queue_Control *the_thread_queue,
1107  const char *name
1108 );
1109 
1110 #if defined(RTEMS_SMP) && defined(RTEMS_DEBUG) && defined(RTEMS_PROFILING)
1111  #define THREAD_QUEUE_INITIALIZER( _name ) \
1112  { \
1113  .Lock_stats = SMP_LOCK_STATS_INITIALIZER( _name ), \
1114  .owner = SMP_LOCK_NO_OWNER, \
1115  .Queue = { \
1116  .Lock = SMP_TICKET_LOCK_INITIALIZER, \
1117  .heads = NULL, \
1118  .owner = NULL, \
1119  .name = _name \
1120  } \
1121  }
1122 #elif defined(RTEMS_SMP) && defined(RTEMS_DEBUG)
1123  #define THREAD_QUEUE_INITIALIZER( _name ) \
1124  { \
1125  .owner = SMP_LOCK_NO_OWNER, \
1126  .Queue = { \
1127  .Lock = SMP_TICKET_LOCK_INITIALIZER, \
1128  .heads = NULL, \
1129  .owner = NULL, \
1130  .name = _name \
1131  } \
1132  }
1133 #elif defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
1134  #define THREAD_QUEUE_INITIALIZER( _name ) \
1135  { \
1136  .Lock_stats = SMP_LOCK_STATS_INITIALIZER( _name ), \
1137  .Queue = { \
1138  .Lock = SMP_TICKET_LOCK_INITIALIZER, \
1139  .heads = NULL, \
1140  .owner = NULL, \
1141  .name = _name \
1142  } \
1143  }
1144 #elif defined(RTEMS_SMP)
1145  #define THREAD_QUEUE_INITIALIZER( _name ) \
1146  { \
1147  .Queue = { \
1148  .Lock = SMP_TICKET_LOCK_INITIALIZER, \
1149  .heads = NULL, \
1150  .owner = NULL, \
1151  .name = _name \
1152  } \
1153  }
1154 #else
1155  #define THREAD_QUEUE_INITIALIZER( _name ) \
1156  { \
1157  .Queue = { \
1158  .heads = NULL, \
1159  .owner = NULL, \
1160  .name = _name \
1161  } \
1162  }
1163 #endif
1164 
1165 RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy(
1166  Thread_queue_Control *the_thread_queue
1167 )
1168 {
1169 #if defined(RTEMS_SMP)
1170  _SMP_ticket_lock_Destroy( &the_thread_queue->Queue.Lock );
1171  _SMP_lock_Stats_destroy( &the_thread_queue->Lock_stats );
1172 #endif
1173 }
1174 
1175 #if defined(RTEMS_MULTIPROCESSING)
1176 void _Thread_queue_MP_callout_do_nothing(
1177  Thread_Control *the_proxy,
1178  Objects_Id mp_id
1179 );
1180 
1181 void _Thread_queue_Unblock_proxy(
1182  Thread_queue_Queue *queue,
1183  Thread_Control *the_thread
1184 );
1185 #endif
1186 
1187 #if defined(RTEMS_SMP)
1188 bool _Thread_queue_Path_acquire_critical(
1189  Thread_queue_Queue *queue,
1190  Thread_Control *the_thread,
1191  Thread_queue_Context *queue_context
1192 );
1193 
1194 void _Thread_queue_Path_release_critical(
1195  Thread_queue_Context *queue_context
1196 );
1197 #endif
1198 
1205 typedef struct {
1206  Objects_Control Object;
1207  Thread_queue_Control Wait_queue;
1209 
1210 #define THREAD_QUEUE_OBJECT_ASSERT( object_type, wait_queue_member, msg ) \
1211  RTEMS_STATIC_ASSERT( \
1212  offsetof( object_type, wait_queue_member ) \
1213  == offsetof( Thread_queue_Object, Wait_queue ) \
1214  && RTEMS_HAVE_MEMBER_SAME_TYPE( \
1215  object_type, \
1216  wait_queue_member, \
1217  Thread_queue_Object, \
1218  Wait_queue \
1219  ), \
1220  msg \
1221  )
1222 
1223 #define THREAD_QUEUE_QUEUE_TO_OBJECT( queue ) \
1224  RTEMS_CONTAINER_OF( \
1225  queue, \
1226  Thread_queue_Object, \
1227  Wait_queue.Queue \
1228  )
1229 
1230 extern const Thread_queue_Operations _Thread_queue_Operations_default;
1231 
1232 extern const Thread_queue_Operations _Thread_queue_Operations_FIFO;
1233 
1234 extern const Thread_queue_Operations _Thread_queue_Operations_priority;
1235 
1236 extern const Thread_queue_Operations _Thread_queue_Operations_priority_inherit;
1237 
1244 extern const char _Thread_queue_Object_name[];
1245 
1255  Thread_queue_Control *the_thread_queue
1256 );
1257 
1260 #ifdef __cplusplus
1261 }
1262 #endif
1263 
1264 #endif
1265 /* end of include file */
Watchdog_Interval ticks
The timeout in ticks.
Definition: threadq.h:227
Thread_Control * owner
The thread queue owner.
Definition: threadq.h:426
RTEMS_INLINE_ROUTINE void _Chain_Append_unprotected(Chain_Control *the_chain, Chain_Node *the_node)
Append a node (unprotected).
Definition: chainimpl.h:679
SuperCore SMP Support API.
void _Thread_queue_Object_initialize(Thread_queue_Control *the_thread_queue)
Initializes a thread queue embedded in an object with identifier.
Definition: threadq.c:148
union Thread_queue_Context::@3980 Timeout
Interval to wait.
Definition: objectdata.h:39
RTEMS_INLINE_ROUTINE Thread_Control * _Thread_queue_First_locked(Thread_queue_Control *the_thread_queue, const Thread_queue_Operations *operations)
Returns the first thread on the thread queue if it exists, otherwise NULL.
Definition: threadqimpl.h:971
Thread queue context for the thread queue methods.
Definition: threadq.h:193
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:65
Thread_Control * update[2]
Threads to update the priority via _Thread_Priority_update().
Definition: threadq.h:288
void _Thread_queue_Extract(Thread_Control *the_thread)
Extracts thread from thread queue.
Definition: threadqenqueue.c:623
Thread_queue_Enqueue_callout enqueue_callout
The enqueue callout for _Thread_queue_Enqueue().
Definition: threadq.h:216
Thread_Control *(* Thread_queue_Flush_filter)(Thread_Control *the_thread, Thread_queue_Queue *queue, Thread_queue_Context *queue_context)
Thread queue flush filter function.
Definition: threadqimpl.h:1021
Thread_queue_Deadlock_callout deadlock_callout
Invoked in case of a detected deadlock.
Definition: threadq.h:299
Definition: chain.h:83
Thread_Control * _Thread_queue_Flush_default_filter(Thread_Control *the_thread, Thread_queue_Queue *queue, Thread_queue_Context *queue_context)
Default thread queue flush filter function.
Definition: threadqflush.c:25
Thread_Control * _Thread_queue_Flush_status_object_was_deleted(Thread_Control *the_thread, Thread_queue_Queue *queue, Thread_queue_Context *queue_context)
Status object was deleted thread queue flush filter function.
Definition: threadqflush.c:36
Definition: threadq.h:547
void _Thread_queue_Enqueue(Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, Thread_queue_Context *queue_context)
Blocks the thread and places it on the thread queue.
Definition: threadqenqueue.c:379
Thread_Control * _Thread_queue_First(Thread_queue_Control *the_thread_queue, const Thread_queue_Operations *operations)
Returns the first thread on the thread queue if it exists, otherwise NULL.
Definition: threadqfirst.c:23
#define _ISR_Get_level()
Return current interrupt level.
Definition: isrlevel.h:125
RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_timeout_ticks(Thread_queue_Context *queue_context, Watchdog_Interval ticks)
Sets the timeout ticks in the thread queue context.
Definition: threadqimpl.h:151
Thread_queue_First_operation first
Thread queue first operation.
Definition: threadq.h:540
void(* Thread_queue_Deadlock_callout)(Thread_Control *the_thread)
Thread queue deadlock callout.
Definition: threadq.h:81
RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_enqueue_callout(Thread_queue_Context *queue_context, Thread_queue_Enqueue_callout enqueue_callout)
Sets the enqueue callout in the thread queue context.
Definition: threadqimpl.h:185
Thread_queue_Priority_queue Priority
This is the set of threads for priority discipline waiting.
Definition: threadq.h:373
RTEMS_INLINE_ROUTINE void _Chain_Initialize_empty(Chain_Control *the_chain)
Initialize this chain as empty.
Definition: chainimpl.h:504
RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_timeout_argument(Thread_queue_Context *queue_context, const void *arg)
Sets the timeout argument in the thread queue context.
Definition: threadqimpl.h:168
Constants and Structures Needed to Declare a Thread Queue.
RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_deadlock_callout(Thread_queue_Context *queue_context, Thread_queue_Deadlock_callout deadlock_callout)
Sets the deadlock callout in the thread queue context.
Definition: threadqimpl.h:280
RTEMS_INLINE_ROUTINE void _Thread_queue_Context_initialize(Thread_queue_Context *queue_context)
Initializes a thread queue context.
Definition: threadqimpl.h:108
Definition: threadq.h:397
void _Thread_queue_Surrender(Thread_queue_Queue *queue, Thread_queue_Heads *heads, Thread_Control *previous_owner, Thread_queue_Context *queue_context, const Thread_queue_Operations *operations)
Surrenders the thread queue previously owned by the thread to the first enqueued thread.
Definition: threadqenqueue.c:659
Thread queue operations.
Definition: threadq.h:512
size_t update_count
Count of threads to update the priority via _Thread_Priority_update().
Definition: threadq.h:279
RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_enqueue_do_nothing_extra(Thread_queue_Context *queue_context)
Sets the do nothing enqueue callout in the thread queue context.
Definition: threadqimpl.h:201
Thread_queue_Queue Queue
The actual thread queue.
Definition: threadq.h:578
Thread_queue_Heads * heads
Lock to protect this thread queue.
Definition: threadq.h:421
Thread queue heads.
Definition: threadq.h:355
const char _Thread_queue_Object_name[]
The special thread queue name to indicated that the thread queue is embedded in an object with identi...
Definition: threadq.c:135
Chain_Control Free_chain
A chain with free thread queue heads providing the spare thread queue heads for a thread once it is d...
Definition: threadq.h:381
Priority_Aggregation Queue
The actual thread priority queue.
Definition: threadq.h:333
#define _ISR_lock_ISR_disable(_context)
Disables interrupts and saves the previous interrupt state in the ISR lock context.
Definition: isrlock.h:383
uint32_t ISR_Level
Definition: isrlevel.h:38
Definition: thread.h:728
Thread queue with a layout compatible to struct _Thread_queue_Queue defined in Newlib <sys/lock...
Definition: threadqimpl.h:51
size_t _Thread_queue_Flush_critical(Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_queue_Flush_filter filter, Thread_queue_Context *queue_context)
Unblocks all threads enqueued on the thread queue.
Definition: threadqflush.c:62
#define _ISR_lock_ISR_enable(_context)
Restores the saved interrupt state of the ISR lock context.
Definition: isrlock.h:404
Per CPU Core Structure.
Definition: percpu.h:290
struct Thread_queue_Context::@3981 Priority
Block to manage thread priority changes due to a thread queue operation.
const char * name
The thread queue name.
Definition: threadq.h:431
void _Thread_queue_Extract_critical(Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, Thread_queue_Context *queue_context)
Extracts the thread from the thread queue and unblocks it.
Definition: threadqenqueue.c:599
Thread_queue_Lock_context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:198
void(* Thread_queue_Enqueue_callout)(Thread_queue_Queue *queue, Thread_Control *the_thread, struct Per_CPU_Control *cpu_self, Thread_queue_Context *queue_context)
Thread queue enqueue callout.
Definition: threadq.h:67
RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(Thread_queue_Context *queue_context, const struct timespec *abstime)
Sets the enqueue callout to add an absolute monotonic timeout in timespec format. ...
Definition: threadqimpl.h:237
bool _Thread_queue_Extract_locked(Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, Thread_queue_Context *queue_context)
Extracts the thread from the thread queue, restores the default wait operations and restores the defa...
Definition: threadqenqueue.c:564
Chain Handler API.
RTEMS_INLINE_ROUTINE void _Chain_Initialize_node(Chain_Node *the_node)
Initializes a chain node.
Definition: chainimpl.h:119
Thread_Control * _Thread_queue_Flush_status_unavailable(Thread_Control *the_thread, Thread_queue_Queue *queue, Thread_queue_Context *queue_context)
Status unavailable thread queue flush filter function.
Definition: threadqflush.c:49
void _Thread_queue_Deadlock_fatal(Thread_Control *the_thread)
Results in an INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK fatal error.
Definition: threadqenqueue.c:374
uint32_t States_Control
Definition: states.h:41
States_Control thread_state
The thread state for _Thread_queue_Enqueue().
Definition: threadq.h:203
uint32_t Watchdog_Interval
Type is used to specify the length of intervals.
Definition: watchdogticks.h:36
RTEMS_INLINE_ROUTINE void _ISR_lock_Context_set_level(ISR_lock_Context *context, ISR_Level level)
Sets the ISR level in the ISR lock context.
Definition: isrlock.h:159
Chain_Node Free_node
A chain node to add these thread queue heads to the free chain of the thread queue heads dedicated to...
Definition: threadq.h:387
size_t _Thread_queue_Queue_get_name_and_id(const Thread_queue_Queue *queue, char *buffer, size_t buffer_size, Objects_Id *id)
Copies the thread queue name to the specified buffer.
Definition: threadq.c:163
const Scheduler_Control _Scheduler_Table[]
Registered schedulers.
RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_thread_state(Thread_queue_Context *queue_context, States_Control thread_state)
Sets the thread state for the thread to enqueue in the thread queue context.
Definition: threadqimpl.h:134
const void * arg
The timeout argument, e.g. pointer to struct timespec.
Definition: threadq.h:232
RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_enqueue_timeout_ticks(Thread_queue_Context *queue_context, Watchdog_Interval ticks)
Sets the enqueue callout to add a relative monotonic timeout in ticks.
Definition: threadqimpl.h:218
RTEMS_INLINE_ROUTINE Per_CPU_Control * _Thread_Dispatch_disable_critical(const ISR_lock_Context *lock_context)
Disables thread dispatching inside a critical section (interrupts disabled).
Definition: threaddispatch.h:175
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
ISR_lock_Context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:125
#define _Thread_queue_Context_set_MP_callout(queue_context, mp_callout)
Sets the MP callout in the thread queue context.
Definition: threadqimpl.h:370
void _Thread_queue_Unblock_critical(bool unblock, Thread_queue_Queue *queue, Thread_Control *the_thread, ISR_lock_Context *lock_context)
Unblocks the thread which was on the thread queue before.
Definition: threadqenqueue.c:578
uint32_t Objects_Id
Definition: object.h:75
void _Thread_queue_Extract_with_proxy(Thread_Control *the_thread)
Extracts the_thread from the_thread_queue.
Definition: threadqextractwithproxy.c:30
void _Thread_queue_Deadlock_status(Thread_Control *the_thread)
Sets the thread wait return code to STATUS_DEADLOCK.
Definition: threadqenqueue.c:369
Constants and Structures Associated with the Scheduler.
Constants and Structures Related with the Thread Control Block.
RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(Thread_queue_Context *queue_context, const struct timespec *abstime)
Sets the enqueue callout to add an absolute realtime timeout in timespec format.
Definition: threadqimpl.h:257
Helper structure to ensure that all objects containing a thread queue have the right layout...
Definition: threadqimpl.h:1205
#define NULL
Requests a GPIO pin group configuration.
Definition: bestcomm_api.h:77
#define _Scheduler_Count
Count of registered schedulers.
Definition: scheduler.h:314