File indexing completed on 2025-05-11 08:24:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef _TX_THREAD_QUEUE_H
0038 #define _TX_THREAD_QUEUE_H
0039
0040 #include "tx-support.h"
0041
0042 #include <rtems/test-scheduler.h>
0043 #include <rtems/score/atomic.h>
0044 #include <rtems/score/status.h>
0045
0046 #include <setjmp.h>
0047
0048 #ifdef __cplusplus
0049 extern "C" {
0050 #endif
0051
0052
0053
0054
0055
0056
0057
0058 typedef enum {
0059 TQ_NODE_ONLY,
0060 TQ_NODE_VITAL,
0061 TQ_NODE_DISPENSABLE
0062 } TQNodeKind;
0063
0064 typedef enum {
0065 TQ_WAIT_STATE_BLOCKED,
0066 TQ_WAIT_STATE_INTEND_TO_BLOCK,
0067 TQ_WAIT_STATE_READY_AGAIN
0068 } TQWaitState;
0069
0070 typedef enum {
0071 TQ_BLOCKER_A,
0072 TQ_BLOCKER_B,
0073 TQ_BLOCKER_C,
0074 TQ_BLOCKER_D,
0075 TQ_BLOCKER_E,
0076 TQ_WORKER_F,
0077 TQ_HELPER_A,
0078 TQ_HELPER_B,
0079 TQ_HELPER_C,
0080 TQ_WORKER_COUNT
0081 } TQWorkerKind;
0082
0083 typedef enum {
0084 TQ_MUTEX_A,
0085 TQ_MUTEX_B,
0086 TQ_MUTEX_C,
0087 TQ_MUTEX_D,
0088 TQ_MUTEX_NO_PROTOCOL,
0089 TQ_MUTEX_FIFO,
0090 TQ_MUTEX_COUNT
0091 } TQMutex;
0092
0093 typedef enum {
0094 TQ_FIFO,
0095 TQ_PRIORITY
0096 } TQDiscipline;
0097
0098 typedef enum {
0099 TQ_NO_WAIT,
0100 TQ_WAIT_FOREVER,
0101 TQ_WAIT_TIMED
0102 } TQWait;
0103
0104 typedef enum {
0105 TQ_DEADLOCK_STATUS,
0106 TQ_DEADLOCK_FATAL
0107 } TQDeadlock;
0108
0109 typedef enum {
0110 TQ_EVENT_ENQUEUE_PREPARE = RTEMS_EVENT_0,
0111 TQ_EVENT_ENQUEUE = RTEMS_EVENT_1,
0112 TQ_EVENT_ENQUEUE_DONE = RTEMS_EVENT_2,
0113 TQ_EVENT_SURRENDER = RTEMS_EVENT_3,
0114 TQ_EVENT_RUNNER_SYNC = RTEMS_EVENT_4,
0115 TQ_EVENT_RUNNER_SYNC_2 = RTEMS_EVENT_5,
0116 TQ_EVENT_HELPER_A_SYNC = RTEMS_EVENT_6,
0117 TQ_EVENT_HELPER_B_SYNC = RTEMS_EVENT_7,
0118 TQ_EVENT_MUTEX_A_OBTAIN = RTEMS_EVENT_8,
0119 TQ_EVENT_MUTEX_A_RELEASE = RTEMS_EVENT_9,
0120 TQ_EVENT_MUTEX_B_OBTAIN = RTEMS_EVENT_10,
0121 TQ_EVENT_MUTEX_B_RELEASE = RTEMS_EVENT_11,
0122 TQ_EVENT_BUSY_WAIT = RTEMS_EVENT_12,
0123 TQ_EVENT_FLUSH_ALL = RTEMS_EVENT_13,
0124 TQ_EVENT_FLUSH_PARTIAL = RTEMS_EVENT_14,
0125 TQ_EVENT_SCHEDULER_RECORD_START = RTEMS_EVENT_15,
0126 TQ_EVENT_SCHEDULER_RECORD_STOP = RTEMS_EVENT_16,
0127 TQ_EVENT_TIMEOUT = RTEMS_EVENT_17,
0128 TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN = RTEMS_EVENT_18,
0129 TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE = RTEMS_EVENT_19,
0130 TQ_EVENT_ENQUEUE_FATAL = RTEMS_EVENT_20,
0131 TQ_EVENT_MUTEX_C_OBTAIN = RTEMS_EVENT_21,
0132 TQ_EVENT_MUTEX_C_RELEASE = RTEMS_EVENT_22,
0133 TQ_EVENT_MUTEX_FIFO_OBTAIN = RTEMS_EVENT_23,
0134 TQ_EVENT_MUTEX_FIFO_RELEASE = RTEMS_EVENT_24,
0135 TQ_EVENT_ENQUEUE_TIMED = RTEMS_EVENT_25,
0136 TQ_EVENT_MUTEX_D_OBTAIN = RTEMS_EVENT_26,
0137 TQ_EVENT_MUTEX_D_RELEASE = RTEMS_EVENT_27,
0138 TQ_EVENT_PIN = RTEMS_EVENT_28,
0139 TQ_EVENT_UNPIN = RTEMS_EVENT_29,
0140 TQ_EVENT_COUNT = RTEMS_EVENT_30
0141 } TQEvent;
0142
0143 typedef enum {
0144 TQ_ENQUEUE_BLOCKS,
0145 TQ_ENQUEUE_STICKY
0146 } TQEnqueueVariant;
0147
0148 typedef struct TQContext {
0149
0150
0151
0152 TQDiscipline discipline;
0153
0154
0155
0156
0157
0158
0159 TQWait wait;
0160
0161
0162
0163
0164 TQEnqueueVariant enqueue_variant;
0165
0166
0167
0168
0169 TQDeadlock deadlock;
0170
0171
0172
0173
0174 rtems_id runner_id;
0175
0176
0177
0178
0179 rtems_tcb *runner_tcb;
0180
0181
0182
0183
0184 rtems_id worker_id[ TQ_WORKER_COUNT ];
0185
0186
0187
0188
0189
0190 rtems_tcb *worker_tcb[ TQ_WORKER_COUNT ];
0191
0192
0193
0194
0195
0196 volatile bool event_received[ TQ_WORKER_COUNT ];
0197
0198
0199
0200
0201 volatile bool busy_wait[ TQ_WORKER_COUNT ];
0202
0203
0204
0205
0206
0207 volatile bool done[ TQ_WORKER_COUNT ];
0208
0209
0210
0211
0212 Atomic_Uint counter;
0213
0214
0215
0216
0217
0218 uint32_t worker_counter[ TQ_WORKER_COUNT ];
0219
0220
0221
0222
0223
0224 Status_Control status[ TQ_WORKER_COUNT ];
0225
0226 union {
0227
0228
0229
0230
0231 rtems_id thread_queue_id;
0232
0233
0234
0235
0236
0237 void *thread_queue_object;
0238 };
0239
0240
0241
0242
0243
0244 rtems_id mutex_id[ TQ_MUTEX_COUNT ];
0245
0246
0247
0248
0249 T_scheduler_log_40 scheduler_log;
0250
0251
0252
0253
0254 void ( *get_properties )( struct TQContext *, TQWorkerKind );
0255
0256
0257
0258
0259 Status_Control ( *convert_status )( Status_Control );
0260
0261
0262
0263
0264 uint32_t how_many;
0265
0266
0267
0268
0269
0270 uint32_t flush_count;
0271
0272
0273
0274
0275
0276 jmp_buf before_enqueue;
0277
0278
0279
0280
0281 void ( *enqueue_prepare )( struct TQContext * );
0282
0283
0284
0285
0286 Status_Control ( *enqueue )( struct TQContext *, TQWait );
0287
0288
0289
0290
0291 void ( *enqueue_done )( struct TQContext * );
0292
0293
0294
0295
0296 Status_Control ( *surrender )( struct TQContext * );
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306 uint32_t ( *flush )( struct TQContext *, uint32_t, bool );
0307
0308
0309
0310
0311 rtems_tcb *( *get_owner )( struct TQContext * );
0312 } TQContext;
0313
0314 void TQSend(
0315 TQContext *ctx,
0316 TQWorkerKind worker,
0317 rtems_event_set events
0318 );
0319
0320 void TQSendAndWaitForExecutionStop(
0321 TQContext *ctx,
0322 TQWorkerKind worker,
0323 rtems_event_set events
0324 );
0325
0326 void TQSendAndWaitForIntendToBlock(
0327 TQContext *ctx,
0328 TQWorkerKind worker,
0329 rtems_event_set events
0330 );
0331
0332 void TQSendAndWaitForExecutionStopOrIntendToBlock(
0333 TQContext *ctx,
0334 TQWorkerKind worker,
0335 rtems_event_set events
0336 );
0337
0338 void TQSendAndSynchronizeRunner(
0339 TQContext *ctx,
0340 TQWorkerKind worker,
0341 rtems_event_set events
0342 );
0343
0344 void TQWaitForEventsReceived( const TQContext *ctx, TQWorkerKind worker );
0345
0346 void TQWaitForIntendToBlock( const TQContext *ctx, TQWorkerKind worker );
0347
0348 void TQWaitForExecutionStop( const TQContext *ctx, TQWorkerKind worker );
0349
0350 void TQClearDone( TQContext *ctx, TQWorkerKind worker );
0351
0352 void TQWaitForDone( const TQContext *ctx, TQWorkerKind worker );
0353
0354 void TQSynchronizeRunner( void );
0355
0356 void TQSynchronizeRunner2( void );
0357
0358 void TQResetCounter( TQContext *ctx );
0359
0360 uint32_t TQGetCounter( const TQContext *ctx );
0361
0362 uint32_t TQGetWorkerCounter( const TQContext *ctx, TQWorkerKind worker );
0363
0364 void TQMutexObtain( const TQContext *ctx, TQMutex mutex );
0365
0366 void TQMutexRelease( const TQContext *ctx, TQMutex mutex );
0367
0368 void TQSetPriority(
0369 const TQContext *ctx,
0370 TQWorkerKind worker,
0371 Priority priority
0372 );
0373
0374 Priority TQGetPriority( const TQContext *ctx, TQWorkerKind worker );
0375
0376 void TQSetScheduler(
0377 const TQContext *ctx,
0378 TQWorkerKind worker,
0379 rtems_id scheduler_id,
0380 Priority priority
0381 );
0382
0383 void TQInitialize( TQContext *ctx );
0384
0385 void TQDestroy( TQContext *ctx );
0386
0387 void TQReset( TQContext *ctx );
0388
0389 void TQSortMutexesByID( TQContext *ctx );
0390
0391 void TQGetProperties( TQContext *ctx, TQWorkerKind enqueued_worker );
0392
0393 Status_Control TQConvertStatus( TQContext *ctx, Status_Control status );
0394
0395 void TQEnqueuePrepare( TQContext *ctx );
0396
0397 Status_Control TQEnqueue( TQContext *ctx, TQWait wait );
0398
0399 Status_Control TQEnqueueFatal( TQContext *ctx );
0400
0401 void TQEnqueueDone( TQContext *ctx );
0402
0403 Status_Control TQSurrender( TQContext *ctx );
0404
0405 void TQFlush( TQContext *ctx, bool flush_all );
0406
0407 rtems_tcb *TQGetOwner( TQContext *ctx );
0408
0409 void TQSchedulerRecordStart( TQContext *ctx );
0410
0411 void TQSchedulerRecordStop( TQContext *ctx );
0412
0413 const T_scheduler_event *TQGetNextAny( TQContext *ctx, size_t *index );
0414
0415 const T_scheduler_event *TQGetNextBlock( TQContext *ctx, size_t *index );
0416
0417 const T_scheduler_event *TQGetNextUnblock( TQContext *ctx, size_t *index );
0418
0419 const T_scheduler_event *TQGetNextUpdatePriority(
0420 TQContext *ctx,
0421 size_t *index
0422 );
0423
0424 const T_scheduler_event *TQGetNextAskForHelp( TQContext *ctx, size_t *index );
0425
0426 void TQDoNothing( TQContext *ctx );
0427
0428 Status_Control TQDoNothingSuccessfully( TQContext *ctx );
0429
0430 Status_Control TQConvertStatusClassic( Status_Control status );
0431
0432 Status_Control TQConvertStatusPOSIX( Status_Control status );
0433
0434 void TQEnqueuePrepareDefault( TQContext *ctx );
0435
0436 void TQEnqueueDoneDefault( TQContext *ctx );
0437
0438 Status_Control TQEnqueueClassicSem( TQContext *ctx, TQWait wait );
0439
0440 Status_Control TQSurrenderClassicSem( TQContext *ctx );
0441
0442 rtems_tcb *TQGetOwnerClassicSem( TQContext *ctx );
0443
0444 typedef enum {
0445 TQ_SEM_BINARY,
0446 TQ_SEM_COUNTING
0447 } TQSemVariant;
0448
0449 typedef struct TQSemContext {
0450
0451
0452
0453 TQContext base;
0454
0455
0456
0457
0458 TQSemVariant variant;
0459
0460
0461
0462
0463 uint32_t ( *get_count )( struct TQSemContext * );
0464
0465
0466
0467
0468 void ( *set_count )( struct TQSemContext *, uint32_t );
0469 } TQSemContext;
0470
0471 Status_Control TQSemSurrender( TQSemContext *ctx );
0472
0473 uint32_t TQSemGetCount( TQSemContext *ctx );
0474
0475 void TQSemSetCount( TQSemContext *ctx, uint32_t count );
0476
0477 Status_Control TQSemSurrenderClassic( TQSemContext *ctx );
0478
0479 uint32_t TQSemGetCountClassic( TQSemContext *ctx );
0480
0481 void TQSemSetCountClassic( TQSemContext *ctx, uint32_t count );
0482
0483 typedef enum {
0484 TQ_MTX_NO_PROTOCOL,
0485 TQ_MTX_PRIORITY_INHERIT,
0486 TQ_MTX_PRIORITY_CEILING,
0487 TQ_MTX_MRSP
0488 } TQMtxProtocol;
0489
0490 typedef enum {
0491 TQ_MTX_RECURSIVE_ALLOWED,
0492 TQ_MTX_RECURSIVE_DEADLOCK,
0493 TQ_MTX_RECURSIVE_UNAVAILABLE
0494 } TQMtxRecursive;
0495
0496 typedef enum {
0497 TQ_MTX_NO_OWNER_CHECK,
0498 TQ_MTX_CHECKS_OWNER
0499 } TQMtxOwnerCheck;
0500
0501 typedef struct TQMtxContext {
0502
0503
0504
0505 TQContext base;
0506
0507
0508
0509
0510 TQMtxProtocol protocol;
0511
0512
0513
0514
0515 TQMtxRecursive recursive;
0516
0517
0518
0519
0520 TQMtxOwnerCheck owner_check;
0521
0522
0523
0524
0525
0526
0527
0528 rtems_task_priority priority_ceiling;
0529 } TQMtxContext;
0530
0531
0532
0533 #ifdef __cplusplus
0534 }
0535 #endif
0536
0537 #endif