File indexing completed on 2025-05-11 08:24:52
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 <rtems.h>
0056 #include <rtems/score/threaddispatch.h>
0057
0058 #include "ts-config.h"
0059 #include "tx-support.h"
0060
0061 #include <rtems/test.h>
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 typedef struct {
0123
0124
0125
0126 rtems_id mutex_id;
0127
0128
0129
0130
0131 rtems_id mutex_2_id;
0132
0133
0134
0135
0136 volatile bool done;
0137
0138
0139
0140
0141 volatile bool done_2;
0142 } RtemsSemValSmp_Context;
0143
0144 static RtemsSemValSmp_Context
0145 RtemsSemValSmp_Instance;
0146
0147 typedef RtemsSemValSmp_Context Context;
0148
0149 static void BadEnqueueFatal(
0150 rtems_fatal_source source,
0151 rtems_fatal_code code,
0152 void *arg
0153 )
0154 {
0155 Per_CPU_Control *cpu_self;
0156 Context *ctx;
0157
0158 T_eq_int( source, INTERNAL_ERROR_CORE );
0159 T_eq_ulong(
0160 code,
0161 INTERNAL_ERROR_THREAD_QUEUE_ENQUEUE_STICKY_FROM_BAD_STATE
0162 );
0163
0164 SetFatalHandler( NULL, NULL );
0165
0166 _ISR_Set_level( 0 );
0167 cpu_self = _Per_CPU_Get();
0168 _Thread_Dispatch_unnest( cpu_self );
0169 _Thread_Dispatch_unnest( cpu_self );
0170
0171 ctx = arg;
0172 ctx->done = true;
0173 SuspendSelf();
0174 }
0175
0176 static void BadEnqueueTask( rtems_task_argument arg )
0177 {
0178 Context *ctx;
0179
0180 ctx = (Context *) arg;
0181 (void) _Thread_Dispatch_disable();
0182 ObtainMutex( ctx->mutex_id );
0183 }
0184
0185 static void ObtainReleaseMrsPTask( rtems_task_argument arg )
0186 {
0187 Context *ctx;
0188
0189 ctx = (Context *) arg;
0190 ObtainMutex( ctx->mutex_2_id );
0191 ctx->done = true;
0192 ObtainMutex( ctx->mutex_id );
0193 ReleaseMutex( ctx->mutex_id );
0194 ReleaseMutex( ctx->mutex_2_id );
0195 ctx->done = true;
0196 SuspendSelf();
0197 }
0198
0199 static void ObtainRelease2Task( rtems_task_argument arg )
0200 {
0201 Context *ctx;
0202
0203 ctx = (Context *) arg;
0204 ctx->done_2 = true;
0205 ObtainMutex( ctx->mutex_2_id );
0206 ReleaseMutex( ctx->mutex_2_id );
0207 ctx->done_2 = true;
0208 SuspendSelf();
0209 }
0210
0211 static void RtemsSemValSmp_Setup( RtemsSemValSmp_Context *ctx )
0212 {
0213 SetSelfPriority( PRIO_NORMAL );
0214 }
0215
0216 static void RtemsSemValSmp_Setup_Wrap( void *arg )
0217 {
0218 RtemsSemValSmp_Context *ctx;
0219
0220 ctx = arg;
0221 RtemsSemValSmp_Setup( ctx );
0222 }
0223
0224 static void RtemsSemValSmp_Teardown( RtemsSemValSmp_Context *ctx )
0225 {
0226 RestoreRunnerPriority();
0227 }
0228
0229 static void RtemsSemValSmp_Teardown_Wrap( void *arg )
0230 {
0231 RtemsSemValSmp_Context *ctx;
0232
0233 ctx = arg;
0234 RtemsSemValSmp_Teardown( ctx );
0235 }
0236
0237 static T_fixture RtemsSemValSmp_Fixture = {
0238 .setup = RtemsSemValSmp_Setup_Wrap,
0239 .stop = NULL,
0240 .teardown = RtemsSemValSmp_Teardown_Wrap,
0241 .scope = NULL,
0242 .initial_context = &RtemsSemValSmp_Instance
0243 };
0244
0245
0246
0247
0248
0249 static void RtemsSemValSmp_Action_0( RtemsSemValSmp_Context *ctx )
0250 {
0251 rtems_status_code sc;
0252 rtems_id worker_id;
0253 rtems_id scheduler_b_id;
0254
0255 ctx->done = false;
0256
0257 sc = rtems_scheduler_ident( TEST_SCHEDULER_B_NAME, &scheduler_b_id );
0258 T_rsc_success( sc );
0259
0260 sc = rtems_semaphore_create(
0261 rtems_build_name( 'M', 'U', 'T', 'X' ),
0262 1,
0263 RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
0264 RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
0265 PRIO_HIGH,
0266 &ctx->mutex_id
0267 );
0268 T_rsc_success( sc );
0269
0270 worker_id = CreateTask( "WORK", PRIO_NORMAL );
0271 SetScheduler( worker_id, scheduler_b_id, PRIO_NORMAL );
0272
0273 ObtainMutex( ctx->mutex_id );
0274 SetFatalHandler( BadEnqueueFatal, ctx );
0275 StartTask( worker_id, BadEnqueueTask, ctx );
0276
0277 while ( !ctx->done ) {
0278
0279 }
0280
0281 DeleteTask( worker_id );
0282 ReleaseMutex( ctx->mutex_id );
0283 DeleteMutex( ctx->mutex_id );
0284 }
0285
0286
0287
0288
0289
0290
0291
0292 static void RtemsSemValSmp_Action_1( RtemsSemValSmp_Context *ctx )
0293 {
0294 rtems_status_code sc;
0295 rtems_id worker_id;
0296 rtems_id worker_2_id;
0297 rtems_id scheduler_b_id;
0298 rtems_task_priority prio;
0299
0300 sc = rtems_scheduler_ident( TEST_SCHEDULER_B_NAME, &scheduler_b_id );
0301 T_rsc_success( sc );
0302
0303 sc = rtems_semaphore_create(
0304 rtems_build_name( 'M', 'U', 'T', 'X' ),
0305 1,
0306 RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
0307 RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
0308 PRIO_HIGH,
0309 &ctx->mutex_id
0310 );
0311 T_rsc_success( sc );
0312
0313 sc = rtems_semaphore_set_priority(
0314 ctx->mutex_id,
0315 scheduler_b_id,
0316 PRIO_HIGH,
0317 &prio
0318 );
0319 T_rsc_success( sc );
0320
0321 ctx->mutex_2_id = CreateMutex();
0322
0323 worker_id = CreateTask( "WORK", PRIO_NORMAL );
0324 SetScheduler( worker_id, scheduler_b_id, PRIO_NORMAL );
0325
0326 worker_2_id = CreateTask( "WRK2", PRIO_NORMAL );
0327 SetScheduler( worker_2_id, scheduler_b_id, PRIO_VERY_HIGH );
0328
0329
0330
0331
0332
0333 ObtainMutex( ctx->mutex_id );
0334 ctx->done = false;
0335 StartTask( worker_id, ObtainReleaseMrsPTask, ctx );
0336
0337 while ( !ctx->done ) {
0338
0339 }
0340
0341 ctx->done = false;
0342 WaitForIntendToBlock( worker_id );
0343 prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
0344 T_eq_u32( prio, PRIO_HIGH );
0345
0346
0347
0348
0349
0350 ctx->done_2 = false;
0351 StartTask( worker_2_id, ObtainRelease2Task, ctx );
0352
0353 while ( !ctx->done_2 ) {
0354
0355 }
0356
0357 ctx->done_2 = false;
0358 WaitForExecutionStop( worker_2_id );
0359 prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
0360 T_eq_u32( prio, PRIO_VERY_HIGH );
0361
0362
0363
0364
0365
0366 SetPriority( worker_id, PRIO_ULTRA_HIGH );
0367
0368 prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
0369 T_eq_u32( prio, PRIO_ULTRA_HIGH );
0370
0371
0372
0373
0374
0375
0376 ReleaseMutex( ctx->mutex_id );
0377
0378 while ( !ctx->done || !ctx->done_2 ) {
0379
0380 }
0381
0382 prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
0383 T_eq_u32( prio, PRIO_ULTRA_HIGH );
0384
0385
0386
0387
0388
0389 ObtainMutex( ctx->mutex_id );
0390
0391
0392
0393
0394
0395 ctx->done = false;
0396 sc = rtems_task_restart( worker_id, (rtems_task_argument) ctx );
0397 T_rsc_success( sc );
0398
0399 while ( !ctx->done ) {
0400
0401 }
0402
0403 ctx->done = false;
0404 WaitForIntendToBlock( worker_id );
0405 prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
0406 T_eq_u32( prio, PRIO_HIGH );
0407
0408
0409
0410
0411
0412 ctx->done_2 = false;
0413 sc = rtems_task_restart( worker_2_id, (rtems_task_argument) ctx );
0414 T_rsc_success( sc );
0415
0416 while ( !ctx->done_2 ) {
0417
0418 }
0419
0420 ctx->done_2 = false;
0421 WaitForExecutionStop( worker_2_id );
0422 prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
0423 T_eq_u32( prio, PRIO_VERY_HIGH );
0424
0425
0426
0427
0428
0429 SetPriority( worker_2_id, PRIO_LOW );
0430
0431 prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
0432 T_eq_u32( prio, PRIO_HIGH );
0433
0434
0435
0436
0437
0438 SetPriority( worker_id, PRIO_ULTRA_HIGH );
0439
0440 prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
0441 T_eq_u32( prio, PRIO_ULTRA_HIGH );
0442
0443
0444
0445
0446
0447
0448 ReleaseMutex( ctx->mutex_id );
0449
0450 while ( !ctx->done || !ctx->done_2 ) {
0451
0452 }
0453
0454 prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
0455 T_eq_u32( prio, PRIO_ULTRA_HIGH );
0456
0457
0458
0459
0460 DeleteTask( worker_id );
0461 DeleteTask( worker_2_id );
0462 DeleteMutex( ctx->mutex_id );
0463 DeleteMutex( ctx->mutex_2_id );
0464 }
0465
0466
0467
0468
0469 T_TEST_CASE_FIXTURE( RtemsSemValSmp, &RtemsSemValSmp_Fixture )
0470 {
0471 RtemsSemValSmp_Context *ctx;
0472
0473 ctx = T_fixture_context();
0474
0475 RtemsSemValSmp_Action_0( ctx );
0476 RtemsSemValSmp_Action_1( ctx );
0477 }
0478
0479