File indexing completed on 2025-05-11 08:24:53
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
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054
0055 #include "tr-tq-enqueue-fifo.h"
0056
0057 #include <rtems/test.h>
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 typedef struct {
0068 uint8_t Skip : 1;
0069 uint8_t Pre_Queue_NA : 1;
0070 uint8_t Post_Position : 2;
0071 } ScoreTqReqEnqueueFifo_Entry;
0072
0073
0074
0075
0076 typedef struct {
0077
0078
0079
0080
0081 TQContext *tq_ctx;
0082
0083 struct {
0084
0085
0086
0087 size_t pcs[ 1 ];
0088
0089
0090
0091
0092 bool in_action_loop;
0093
0094
0095
0096
0097 size_t index;
0098
0099
0100
0101
0102 ScoreTqReqEnqueueFifo_Entry entry;
0103
0104
0105
0106
0107
0108 bool skip;
0109 } Map;
0110 } ScoreTqReqEnqueueFifo_Context;
0111
0112 static ScoreTqReqEnqueueFifo_Context
0113 ScoreTqReqEnqueueFifo_Instance;
0114
0115 static const char * const ScoreTqReqEnqueueFifo_PreDesc_Queue[] = {
0116 "Empty",
0117 "NonEmpty",
0118 "NA"
0119 };
0120
0121 static const char * const * const ScoreTqReqEnqueueFifo_PreDesc[] = {
0122 ScoreTqReqEnqueueFifo_PreDesc_Queue,
0123 NULL
0124 };
0125
0126 typedef ScoreTqReqEnqueueFifo_Context Context;
0127
0128 static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
0129 {
0130 return TQGetNextUnblock( ctx->tq_ctx, index )->thread;
0131 }
0132
0133 static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
0134 {
0135 return ctx->tq_ctx->worker_tcb[ worker ];
0136 }
0137
0138 static void ScoreTqReqEnqueueFifo_Pre_Queue_Prepare(
0139 ScoreTqReqEnqueueFifo_Context *ctx,
0140 ScoreTqReqEnqueueFifo_Pre_Queue state
0141 )
0142 {
0143 switch ( state ) {
0144 case ScoreTqReqEnqueueFifo_Pre_Queue_Empty: {
0145
0146
0147
0148 ctx->tq_ctx->how_many = 1;
0149 break;
0150 }
0151
0152 case ScoreTqReqEnqueueFifo_Pre_Queue_NonEmpty: {
0153
0154
0155
0156 ctx->tq_ctx->how_many = 2;
0157 break;
0158 }
0159
0160 case ScoreTqReqEnqueueFifo_Pre_Queue_NA:
0161 break;
0162 }
0163 }
0164
0165 static void ScoreTqReqEnqueueFifo_Post_Position_Check(
0166 ScoreTqReqEnqueueFifo_Context *ctx,
0167 ScoreTqReqEnqueueFifo_Post_Position state
0168 )
0169 {
0170 size_t i;
0171
0172 i = 0;
0173
0174
0175 T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0176 T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
0177
0178 switch ( state ) {
0179 case ScoreTqReqEnqueueFifo_Post_Position_First: {
0180
0181
0182
0183 T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0184 T_eq_ptr( GetUnblock( ctx, &i ), NULL );
0185 break;
0186 }
0187
0188 case ScoreTqReqEnqueueFifo_Post_Position_Last: {
0189
0190
0191
0192 T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
0193 T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
0194 T_eq_ptr( GetUnblock( ctx, &i ), NULL );
0195 break;
0196 }
0197
0198 case ScoreTqReqEnqueueFifo_Post_Position_NA:
0199 break;
0200 }
0201 }
0202
0203 static void ScoreTqReqEnqueueFifo_Setup( ScoreTqReqEnqueueFifo_Context *ctx )
0204 {
0205 TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_HIGH );
0206 TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B, PRIO_VERY_HIGH );
0207 TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_C, PRIO_ULTRA_HIGH );
0208 }
0209
0210 static void ScoreTqReqEnqueueFifo_Setup_Wrap( void *arg )
0211 {
0212 ScoreTqReqEnqueueFifo_Context *ctx;
0213
0214 ctx = arg;
0215 ctx->Map.in_action_loop = false;
0216 ScoreTqReqEnqueueFifo_Setup( ctx );
0217 }
0218
0219 static void ScoreTqReqEnqueueFifo_Teardown(
0220 ScoreTqReqEnqueueFifo_Context *ctx
0221 )
0222 {
0223 TQReset( ctx->tq_ctx );
0224 }
0225
0226 static void ScoreTqReqEnqueueFifo_Teardown_Wrap( void *arg )
0227 {
0228 ScoreTqReqEnqueueFifo_Context *ctx;
0229
0230 ctx = arg;
0231 ctx->Map.in_action_loop = false;
0232 ScoreTqReqEnqueueFifo_Teardown( ctx );
0233 }
0234
0235 static void ScoreTqReqEnqueueFifo_Action( ScoreTqReqEnqueueFifo_Context *ctx )
0236 {
0237 TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_PREPARE );
0238
0239 if ( ctx->tq_ctx->how_many >= 2 ) {
0240 TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER );
0241 }
0242
0243 TQSchedulerRecordStart( ctx->tq_ctx );
0244 TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER );
0245 TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_DONE );
0246 TQSchedulerRecordStop( ctx->tq_ctx );
0247 }
0248
0249 static const ScoreTqReqEnqueueFifo_Entry
0250 ScoreTqReqEnqueueFifo_Entries[] = {
0251 { 0, 0, ScoreTqReqEnqueueFifo_Post_Position_First },
0252 { 0, 0, ScoreTqReqEnqueueFifo_Post_Position_Last }
0253 };
0254
0255 static const uint8_t
0256 ScoreTqReqEnqueueFifo_Map[] = {
0257 0, 1
0258 };
0259
0260 static size_t ScoreTqReqEnqueueFifo_Scope( void *arg, char *buf, size_t n )
0261 {
0262 ScoreTqReqEnqueueFifo_Context *ctx;
0263
0264 ctx = arg;
0265
0266 if ( ctx->Map.in_action_loop ) {
0267 return T_get_scope( ScoreTqReqEnqueueFifo_PreDesc, buf, n, ctx->Map.pcs );
0268 }
0269
0270 return 0;
0271 }
0272
0273 static T_fixture ScoreTqReqEnqueueFifo_Fixture = {
0274 .setup = ScoreTqReqEnqueueFifo_Setup_Wrap,
0275 .stop = NULL,
0276 .teardown = ScoreTqReqEnqueueFifo_Teardown_Wrap,
0277 .scope = ScoreTqReqEnqueueFifo_Scope,
0278 .initial_context = &ScoreTqReqEnqueueFifo_Instance
0279 };
0280
0281 static inline ScoreTqReqEnqueueFifo_Entry ScoreTqReqEnqueueFifo_PopEntry(
0282 ScoreTqReqEnqueueFifo_Context *ctx
0283 )
0284 {
0285 size_t index;
0286
0287 index = ctx->Map.index;
0288 ctx->Map.index = index + 1;
0289 return ScoreTqReqEnqueueFifo_Entries[
0290 ScoreTqReqEnqueueFifo_Map[ index ]
0291 ];
0292 }
0293
0294 static void ScoreTqReqEnqueueFifo_TestVariant(
0295 ScoreTqReqEnqueueFifo_Context *ctx
0296 )
0297 {
0298 ScoreTqReqEnqueueFifo_Pre_Queue_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0299 ScoreTqReqEnqueueFifo_Action( ctx );
0300 ScoreTqReqEnqueueFifo_Post_Position_Check(
0301 ctx,
0302 ctx->Map.entry.Post_Position
0303 );
0304 }
0305
0306 static T_fixture_node ScoreTqReqEnqueueFifo_Node;
0307
0308 static T_remark ScoreTqReqEnqueueFifo_Remark = {
0309 .next = NULL,
0310 .remark = "ScoreTqReqEnqueueFifo"
0311 };
0312
0313 void ScoreTqReqEnqueueFifo_Run( TQContext *tq_ctx )
0314 {
0315 ScoreTqReqEnqueueFifo_Context *ctx;
0316
0317 ctx = &ScoreTqReqEnqueueFifo_Instance;
0318 ctx->tq_ctx = tq_ctx;
0319
0320 ctx = T_push_fixture(
0321 &ScoreTqReqEnqueueFifo_Node,
0322 &ScoreTqReqEnqueueFifo_Fixture
0323 );
0324 ctx->Map.in_action_loop = true;
0325 ctx->Map.index = 0;
0326
0327 for (
0328 ctx->Map.pcs[ 0 ] = ScoreTqReqEnqueueFifo_Pre_Queue_Empty;
0329 ctx->Map.pcs[ 0 ] < ScoreTqReqEnqueueFifo_Pre_Queue_NA;
0330 ++ctx->Map.pcs[ 0 ]
0331 ) {
0332 ctx->Map.entry = ScoreTqReqEnqueueFifo_PopEntry( ctx );
0333 ScoreTqReqEnqueueFifo_TestVariant( ctx );
0334 }
0335
0336 T_add_remark( &ScoreTqReqEnqueueFifo_Remark );
0337 T_pop_fixture();
0338 }
0339
0340