File indexing completed on 2025-05-11 08:24:51
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
0057 #include "tx-support.h"
0058
0059 #include <rtems/test.h>
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 typedef struct {
0076
0077
0078
0079 rtems_id worker_id;
0080
0081
0082
0083
0084 rtems_status_code status;
0085
0086
0087
0088
0089 T_measure_runtime_context *context;
0090
0091
0092
0093
0094 T_measure_runtime_request request;
0095
0096
0097
0098
0099 T_ticks begin;
0100
0101
0102
0103
0104 T_ticks end;
0105 } RtemsEventValPerf_Context;
0106
0107 static RtemsEventValPerf_Context
0108 RtemsEventValPerf_Instance;
0109
0110 #define EVENT_END RTEMS_EVENT_0
0111
0112 #define EVENT_OTHER RTEMS_EVENT_1
0113
0114 typedef RtemsEventValPerf_Context Context;
0115
0116 static void Send( const Context *ctx, rtems_event_set events )
0117 {
0118 SendEvents( ctx->worker_id, events );
0119 }
0120
0121 static void Satisfy( void *arg )
0122 {
0123 Context *ctx;
0124
0125 ctx = arg;
0126 ctx->begin = T_tick();
0127 ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
0128 }
0129
0130 static void Worker( rtems_task_argument arg )
0131 {
0132 Context *ctx;
0133
0134 ctx = (Context *) arg;
0135
0136 while ( true ) {
0137 rtems_event_set events;
0138 rtems_status_code sc;
0139 T_ticks ticks;
0140
0141 sc = rtems_event_receive(
0142 EVENT_END | EVENT_OTHER,
0143 RTEMS_EVENT_ALL | RTEMS_WAIT,
0144 RTEMS_NO_TIMEOUT,
0145 &events
0146 );
0147 ticks = T_tick();
0148 T_quiet_rsc_success( sc );
0149
0150 if ( ( events & EVENT_END ) != 0 ) {
0151 ctx->end = ticks;
0152 }
0153 }
0154 }
0155
0156 static void RtemsEventValPerf_Setup_Context( RtemsEventValPerf_Context *ctx )
0157 {
0158 T_measure_runtime_config config;
0159
0160 memset( &config, 0, sizeof( config ) );
0161 config.sample_count = 100;
0162 ctx->request.arg = ctx;
0163 ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
0164 ctx->context = T_measure_runtime_create( &config );
0165 T_assert_not_null( ctx->context );
0166 }
0167
0168
0169
0170
0171 static void RtemsEventValPerf_Setup( RtemsEventValPerf_Context *ctx )
0172 {
0173 SetSelfPriority( PRIO_NORMAL );
0174 ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
0175 StartTask( ctx->worker_id, Worker, ctx );
0176 }
0177
0178 static void RtemsEventValPerf_Setup_Wrap( void *arg )
0179 {
0180 RtemsEventValPerf_Context *ctx;
0181
0182 ctx = arg;
0183 RtemsEventValPerf_Setup_Context( ctx );
0184 RtemsEventValPerf_Setup( ctx );
0185 }
0186
0187
0188
0189
0190 static void RtemsEventValPerf_Teardown( RtemsEventValPerf_Context *ctx )
0191 {
0192 DeleteTask( ctx->worker_id );
0193 RestoreRunnerPriority();
0194 }
0195
0196 static void RtemsEventValPerf_Teardown_Wrap( void *arg )
0197 {
0198 RtemsEventValPerf_Context *ctx;
0199
0200 ctx = arg;
0201 RtemsEventValPerf_Teardown( ctx );
0202 }
0203
0204 static T_fixture RtemsEventValPerf_Fixture = {
0205 .setup = RtemsEventValPerf_Setup_Wrap,
0206 .stop = NULL,
0207 .teardown = RtemsEventValPerf_Teardown_Wrap,
0208 .scope = NULL,
0209 .initial_context = &RtemsEventValPerf_Instance
0210 };
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222 static void RtemsEventReqPerfIsrPreempt_Body( RtemsEventValPerf_Context *ctx )
0223 {
0224 CallWithinISR( Satisfy, ctx );
0225 }
0226
0227 static void RtemsEventReqPerfIsrPreempt_Body_Wrap( void *arg )
0228 {
0229 RtemsEventValPerf_Context *ctx;
0230
0231 ctx = arg;
0232 RtemsEventReqPerfIsrPreempt_Body( ctx );
0233 }
0234
0235
0236
0237
0238
0239 static bool RtemsEventReqPerfIsrPreempt_Teardown(
0240 RtemsEventValPerf_Context *ctx,
0241 T_ticks *delta,
0242 uint32_t tic,
0243 uint32_t toc,
0244 unsigned int retry
0245 )
0246 {
0247 T_quiet_rsc_success( ctx->status );
0248
0249 *delta = ctx->end - ctx->begin;
0250
0251 return tic == toc;
0252 }
0253
0254 static bool RtemsEventReqPerfIsrPreempt_Teardown_Wrap(
0255 void *arg,
0256 T_ticks *delta,
0257 uint32_t tic,
0258 uint32_t toc,
0259 unsigned int retry
0260 )
0261 {
0262 RtemsEventValPerf_Context *ctx;
0263
0264 ctx = arg;
0265 return RtemsEventReqPerfIsrPreempt_Teardown( ctx, delta, tic, toc, retry );
0266 }
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 static void RtemsEventReqPerfOther_Setup( RtemsEventValPerf_Context *ctx )
0280 {
0281 SetPriority( ctx->worker_id, PRIO_LOW );
0282 }
0283
0284 static void RtemsEventReqPerfOther_Setup_Wrap( void *arg )
0285 {
0286 RtemsEventValPerf_Context *ctx;
0287
0288 ctx = arg;
0289 RtemsEventReqPerfOther_Setup( ctx );
0290 }
0291
0292
0293
0294
0295 static void RtemsEventReqPerfOther_Body( RtemsEventValPerf_Context *ctx )
0296 {
0297 ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
0298 }
0299
0300 static void RtemsEventReqPerfOther_Body_Wrap( void *arg )
0301 {
0302 RtemsEventValPerf_Context *ctx;
0303
0304 ctx = arg;
0305 RtemsEventReqPerfOther_Body( ctx );
0306 }
0307
0308
0309
0310
0311
0312 static bool RtemsEventReqPerfOther_Teardown(
0313 RtemsEventValPerf_Context *ctx,
0314 T_ticks *delta,
0315 uint32_t tic,
0316 uint32_t toc,
0317 unsigned int retry
0318 )
0319 {
0320 T_quiet_rsc_success( ctx->status );
0321
0322 SetPriority( ctx->worker_id, PRIO_HIGH );
0323
0324 return tic == toc;
0325 }
0326
0327 static bool RtemsEventReqPerfOther_Teardown_Wrap(
0328 void *arg,
0329 T_ticks *delta,
0330 uint32_t tic,
0331 uint32_t toc,
0332 unsigned int retry
0333 )
0334 {
0335 RtemsEventValPerf_Context *ctx;
0336
0337 ctx = arg;
0338 return RtemsEventReqPerfOther_Teardown( ctx, delta, tic, toc, retry );
0339 }
0340
0341
0342
0343 #if defined(RTEMS_SMP)
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353 static void RtemsEventReqPerfOtherCpu_Prepare( RtemsEventValPerf_Context *ctx )
0354 {
0355 SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
0356 }
0357
0358
0359
0360
0361 static void RtemsEventReqPerfOtherCpu_Body( RtemsEventValPerf_Context *ctx )
0362 {
0363 ctx->begin = T_tick();
0364 ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
0365 }
0366
0367 static void RtemsEventReqPerfOtherCpu_Body_Wrap( void *arg )
0368 {
0369 RtemsEventValPerf_Context *ctx;
0370
0371 ctx = arg;
0372 RtemsEventReqPerfOtherCpu_Body( ctx );
0373 }
0374
0375
0376
0377
0378
0379 static bool RtemsEventReqPerfOtherCpu_Teardown(
0380 RtemsEventValPerf_Context *ctx,
0381 T_ticks *delta,
0382 uint32_t tic,
0383 uint32_t toc,
0384 unsigned int retry
0385 )
0386 {
0387 T_quiet_rsc_success( ctx->status );
0388
0389 WaitForNextTask( 1, ctx->worker_id );
0390 *delta = ctx->end - ctx->begin;
0391
0392 return tic == toc;
0393 }
0394
0395 static bool RtemsEventReqPerfOtherCpu_Teardown_Wrap(
0396 void *arg,
0397 T_ticks *delta,
0398 uint32_t tic,
0399 uint32_t toc,
0400 unsigned int retry
0401 )
0402 {
0403 RtemsEventValPerf_Context *ctx;
0404
0405 ctx = arg;
0406 return RtemsEventReqPerfOtherCpu_Teardown( ctx, delta, tic, toc, retry );
0407 }
0408
0409
0410
0411
0412 static void RtemsEventReqPerfOtherCpu_Cleanup( RtemsEventValPerf_Context *ctx )
0413 {
0414 SetScheduler( ctx->worker_id, SCHEDULER_A_ID, PRIO_HIGH );
0415 }
0416
0417
0418 #endif
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430 static void RtemsEventReqPerfOtherNotSatisfied_Body(
0431 RtemsEventValPerf_Context *ctx
0432 )
0433 {
0434 ctx->status = rtems_event_send( ctx->worker_id, EVENT_OTHER );
0435 }
0436
0437 static void RtemsEventReqPerfOtherNotSatisfied_Body_Wrap( void *arg )
0438 {
0439 RtemsEventValPerf_Context *ctx;
0440
0441 ctx = arg;
0442 RtemsEventReqPerfOtherNotSatisfied_Body( ctx );
0443 }
0444
0445
0446
0447
0448
0449 static bool RtemsEventReqPerfOtherNotSatisfied_Teardown(
0450 RtemsEventValPerf_Context *ctx,
0451 T_ticks *delta,
0452 uint32_t tic,
0453 uint32_t toc,
0454 unsigned int retry
0455 )
0456 {
0457 T_quiet_rsc_success( ctx->status );
0458
0459 Send( ctx, EVENT_END );
0460
0461 return tic == toc;
0462 }
0463
0464 static bool RtemsEventReqPerfOtherNotSatisfied_Teardown_Wrap(
0465 void *arg,
0466 T_ticks *delta,
0467 uint32_t tic,
0468 uint32_t toc,
0469 unsigned int retry
0470 )
0471 {
0472 RtemsEventValPerf_Context *ctx;
0473
0474 ctx = arg;
0475 return RtemsEventReqPerfOtherNotSatisfied_Teardown(
0476 ctx,
0477 delta,
0478 tic,
0479 toc,
0480 retry
0481 );
0482 }
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496 static void RtemsEventReqPerfOtherPreempt_Body(
0497 RtemsEventValPerf_Context *ctx
0498 )
0499 {
0500 ctx->begin = T_tick();
0501 ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
0502 }
0503
0504 static void RtemsEventReqPerfOtherPreempt_Body_Wrap( void *arg )
0505 {
0506 RtemsEventValPerf_Context *ctx;
0507
0508 ctx = arg;
0509 RtemsEventReqPerfOtherPreempt_Body( ctx );
0510 }
0511
0512
0513
0514
0515
0516 static bool RtemsEventReqPerfOtherPreempt_Teardown(
0517 RtemsEventValPerf_Context *ctx,
0518 T_ticks *delta,
0519 uint32_t tic,
0520 uint32_t toc,
0521 unsigned int retry
0522 )
0523 {
0524 T_quiet_rsc_success( ctx->status );
0525
0526 *delta = ctx->end - ctx->begin;
0527
0528 return tic == toc;
0529 }
0530
0531 static bool RtemsEventReqPerfOtherPreempt_Teardown_Wrap(
0532 void *arg,
0533 T_ticks *delta,
0534 uint32_t tic,
0535 uint32_t toc,
0536 unsigned int retry
0537 )
0538 {
0539 RtemsEventValPerf_Context *ctx;
0540
0541 ctx = arg;
0542 return RtemsEventReqPerfOtherPreempt_Teardown( ctx, delta, tic, toc, retry );
0543 }
0544
0545
0546
0547
0548
0549
0550 T_TEST_CASE_FIXTURE( RtemsEventValPerf, &RtemsEventValPerf_Fixture )
0551 {
0552 RtemsEventValPerf_Context *ctx;
0553
0554 ctx = T_fixture_context();
0555
0556 ctx->request.name = "RtemsEventReqPerfIsrPreempt";
0557 ctx->request.setup = NULL;
0558 ctx->request.body = RtemsEventReqPerfIsrPreempt_Body_Wrap;
0559 ctx->request.teardown = RtemsEventReqPerfIsrPreempt_Teardown_Wrap;
0560 T_measure_runtime( ctx->context, &ctx->request );
0561
0562 ctx->request.name = "RtemsEventReqPerfOther";
0563 ctx->request.setup = RtemsEventReqPerfOther_Setup_Wrap;
0564 ctx->request.body = RtemsEventReqPerfOther_Body_Wrap;
0565 ctx->request.teardown = RtemsEventReqPerfOther_Teardown_Wrap;
0566 T_measure_runtime( ctx->context, &ctx->request );
0567
0568 #if defined(RTEMS_SMP)
0569 RtemsEventReqPerfOtherCpu_Prepare( ctx );
0570 ctx->request.name = "RtemsEventReqPerfOtherCpu";
0571 ctx->request.setup = NULL;
0572 ctx->request.body = RtemsEventReqPerfOtherCpu_Body_Wrap;
0573 ctx->request.teardown = RtemsEventReqPerfOtherCpu_Teardown_Wrap;
0574 T_measure_runtime( ctx->context, &ctx->request );
0575 RtemsEventReqPerfOtherCpu_Cleanup( ctx );
0576 #endif
0577
0578 ctx->request.name = "RtemsEventReqPerfOtherNotSatisfied";
0579 ctx->request.setup = NULL;
0580 ctx->request.body = RtemsEventReqPerfOtherNotSatisfied_Body_Wrap;
0581 ctx->request.teardown = RtemsEventReqPerfOtherNotSatisfied_Teardown_Wrap;
0582 T_measure_runtime( ctx->context, &ctx->request );
0583
0584 ctx->request.name = "RtemsEventReqPerfOtherPreempt";
0585 ctx->request.setup = NULL;
0586 ctx->request.body = RtemsEventReqPerfOtherPreempt_Body_Wrap;
0587 ctx->request.teardown = RtemsEventReqPerfOtherPreempt_Teardown_Wrap;
0588 T_measure_runtime( ctx->context, &ctx->request );
0589 }
0590
0591