File indexing completed on 2025-05-11 08:24:13
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 #ifndef _RTEMS_SCORE_USEREXTIMPL_H
0039 #define _RTEMS_SCORE_USEREXTIMPL_H
0040
0041 #include <rtems/score/userextdata.h>
0042 #include <rtems/score/chainimpl.h>
0043 #include <rtems/score/isrlock.h>
0044 #include <rtems/score/thread.h>
0045 #include <rtems/score/percpu.h>
0046
0047 #ifdef __cplusplus
0048 extern "C" {
0049 #endif
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 typedef struct User_extensions_Iterator {
0067 Chain_Iterator Iterator;
0068 struct User_extensions_Iterator *previous;
0069 } User_extensions_Iterator;
0070
0071 typedef struct {
0072
0073
0074
0075 Chain_Control Active;
0076
0077
0078
0079
0080 Chain_Iterator_registry Iterators;
0081
0082 #if defined(RTEMS_SMP)
0083
0084
0085
0086
0087 ISR_lock_Control Lock;
0088 #endif
0089 } User_extensions_List;
0090
0091
0092
0093
0094 extern User_extensions_List _User_extensions_List;
0095
0096
0097
0098
0099 extern Chain_Control _User_extensions_Switches_list;
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110 void _User_extensions_Handler_initialization( void );
0111
0112
0113
0114
0115
0116
0117 void _User_extensions_Add_set(
0118 User_extensions_Control *extension
0119 );
0120
0121
0122
0123
0124
0125
0126 static inline void _User_extensions_Add_API_set(
0127 User_extensions_Control *extension
0128 )
0129 {
0130 _User_extensions_Add_set( extension );
0131 }
0132
0133
0134
0135
0136
0137
0138
0139 static inline void _User_extensions_Add_set_with_table(
0140 User_extensions_Control *extension,
0141 const User_extensions_Table *extension_table
0142 )
0143 {
0144 extension->Callouts = *extension_table;
0145
0146 _User_extensions_Add_set( extension );
0147 }
0148
0149
0150
0151
0152
0153
0154 void _User_extensions_Remove_set(
0155 User_extensions_Control *extension
0156 );
0157
0158
0159
0160
0161
0162
0163
0164
0165 typedef void (*User_extensions_Visitor)(
0166 Thread_Control *executing,
0167 void *arg,
0168 const User_extensions_Table *callouts
0169 );
0170
0171 typedef struct {
0172 Thread_Control *created;
0173 bool ok;
0174 } User_extensions_Thread_create_context;
0175
0176
0177
0178
0179
0180
0181
0182
0183 void _User_extensions_Thread_create_visitor(
0184 Thread_Control *executing,
0185 void *arg,
0186 const User_extensions_Table *callouts
0187 );
0188
0189
0190
0191
0192
0193
0194
0195
0196 void _User_extensions_Thread_delete_visitor(
0197 Thread_Control *executing,
0198 void *arg,
0199 const User_extensions_Table *callouts
0200 );
0201
0202
0203
0204
0205
0206
0207
0208
0209 void _User_extensions_Thread_start_visitor(
0210 Thread_Control *executing,
0211 void *arg,
0212 const User_extensions_Table *callouts
0213 );
0214
0215
0216
0217
0218
0219
0220
0221
0222 void _User_extensions_Thread_restart_visitor(
0223 Thread_Control *executing,
0224 void *arg,
0225 const User_extensions_Table *callouts
0226 );
0227
0228
0229
0230
0231
0232
0233
0234
0235 void _User_extensions_Thread_begin_visitor(
0236 Thread_Control *executing,
0237 void *arg,
0238 const User_extensions_Table *callouts
0239 );
0240
0241
0242
0243
0244
0245
0246
0247
0248 void _User_extensions_Thread_exitted_visitor(
0249 Thread_Control *executing,
0250 void *arg,
0251 const User_extensions_Table *callouts
0252 );
0253
0254 typedef struct {
0255 Internal_errors_Source source;
0256 Internal_errors_t error;
0257 } User_extensions_Fatal_context;
0258
0259
0260
0261
0262
0263
0264
0265
0266 void _User_extensions_Fatal_visitor(
0267 Thread_Control *executing,
0268 void *arg,
0269 const User_extensions_Table *callouts
0270 );
0271
0272
0273
0274
0275
0276
0277
0278
0279 void _User_extensions_Thread_terminate_visitor(
0280 Thread_Control *executing,
0281 void *arg,
0282 const User_extensions_Table *callouts
0283 );
0284
0285
0286
0287
0288
0289
0290
0291
0292 void _User_extensions_Iterate(
0293 void *arg,
0294 User_extensions_Visitor visitor,
0295 Chain_Iterator_direction direction
0296 );
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313 static inline bool _User_extensions_Thread_create( Thread_Control *created )
0314 {
0315 User_extensions_Thread_create_context ctx = { created, true };
0316
0317 _User_extensions_Iterate(
0318 &ctx,
0319 _User_extensions_Thread_create_visitor,
0320 CHAIN_ITERATOR_FORWARD
0321 );
0322
0323 return ctx.ok;
0324 }
0325
0326
0327
0328
0329
0330
0331 static inline void _User_extensions_Thread_delete( Thread_Control *deleted )
0332 {
0333 _User_extensions_Iterate(
0334 deleted,
0335 _User_extensions_Thread_delete_visitor,
0336 CHAIN_ITERATOR_BACKWARD
0337 );
0338 }
0339
0340
0341
0342
0343
0344
0345 static inline void _User_extensions_Thread_start( Thread_Control *started )
0346 {
0347 _User_extensions_Iterate(
0348 started,
0349 _User_extensions_Thread_start_visitor,
0350 CHAIN_ITERATOR_FORWARD
0351 );
0352 }
0353
0354
0355
0356
0357
0358
0359 static inline void _User_extensions_Thread_restart( Thread_Control *restarted )
0360 {
0361 _User_extensions_Iterate(
0362 restarted,
0363 _User_extensions_Thread_restart_visitor,
0364 CHAIN_ITERATOR_FORWARD
0365 );
0366 }
0367
0368
0369
0370
0371
0372
0373 static inline void _User_extensions_Thread_begin( Thread_Control *executing )
0374 {
0375 _User_extensions_Iterate(
0376 executing,
0377 _User_extensions_Thread_begin_visitor,
0378 CHAIN_ITERATOR_FORWARD
0379 );
0380 }
0381
0382
0383
0384
0385
0386
0387
0388 static inline void _User_extensions_Thread_switch(
0389 Thread_Control *executing,
0390 Thread_Control *heir
0391 )
0392 {
0393 const Chain_Control *chain;
0394 const Chain_Node *tail;
0395 const Chain_Node *node;
0396
0397 chain = &_User_extensions_Switches_list;
0398 tail = _Chain_Immutable_tail( chain );
0399 node = _Chain_Immutable_first( chain );
0400
0401 if ( node != tail ) {
0402 #if defined(RTEMS_SMP)
0403 ISR_lock_Context lock_context;
0404 Per_CPU_Control *cpu_self;
0405
0406 cpu_self = _Per_CPU_Get();
0407
0408 _ISR_lock_ISR_disable( &lock_context );
0409 _Per_CPU_Acquire( cpu_self, &lock_context );
0410
0411 executing = cpu_self->ancestor;
0412 cpu_self->ancestor = heir;
0413 node = _Chain_Immutable_first( chain );
0414
0415
0416
0417
0418
0419
0420 if ( executing != heir ) {
0421 #endif
0422
0423 while ( node != tail ) {
0424 const User_extensions_Switch_control *extension;
0425
0426 extension = (const User_extensions_Switch_control *) node;
0427 node = _Chain_Immutable_next( node );
0428 (*extension->thread_switch)( executing, heir );
0429 }
0430
0431 #if defined(RTEMS_SMP)
0432 }
0433
0434 _Per_CPU_Release( cpu_self, &lock_context );
0435 _ISR_lock_ISR_enable( &lock_context );
0436 #endif
0437 }
0438 }
0439
0440
0441
0442
0443
0444
0445 static inline void _User_extensions_Thread_exitted( Thread_Control *executing )
0446 {
0447 _User_extensions_Iterate(
0448 executing,
0449 _User_extensions_Thread_exitted_visitor,
0450 CHAIN_ITERATOR_FORWARD
0451 );
0452 }
0453
0454
0455
0456
0457
0458
0459
0460 static inline void _User_extensions_Fatal(
0461 Internal_errors_Source source,
0462 Internal_errors_t error
0463 )
0464 {
0465 User_extensions_Fatal_context ctx = { source, error };
0466
0467 _User_extensions_Iterate(
0468 &ctx,
0469 _User_extensions_Fatal_visitor,
0470 CHAIN_ITERATOR_FORWARD
0471 );
0472 }
0473
0474
0475
0476
0477
0478
0479 static inline void _User_extensions_Thread_terminate(
0480 Thread_Control *executing
0481 )
0482 {
0483 _User_extensions_Iterate(
0484 executing,
0485 _User_extensions_Thread_terminate_visitor,
0486 CHAIN_ITERATOR_BACKWARD
0487 );
0488 }
0489
0490
0491
0492
0493
0494
0495 static inline void _User_extensions_Acquire( ISR_lock_Context *lock_context )
0496 {
0497 _ISR_lock_ISR_disable_and_acquire(
0498 &_User_extensions_List.Lock,
0499 lock_context
0500 );
0501 }
0502
0503
0504
0505
0506
0507
0508 static inline void _User_extensions_Release( ISR_lock_Context *lock_context )
0509 {
0510 _ISR_lock_Release_and_ISR_enable(
0511 &_User_extensions_List.Lock,
0512 lock_context
0513 );
0514 }
0515
0516
0517
0518
0519
0520
0521
0522 static inline void _User_extensions_Destroy_iterators(
0523 Thread_Control *the_thread
0524 )
0525 {
0526 ISR_lock_Context lock_context;
0527 User_extensions_Iterator *iter;
0528
0529 _User_extensions_Acquire( &lock_context );
0530
0531 iter = the_thread->last_user_extensions_iterator;
0532
0533 while ( iter != NULL ) {
0534 _Chain_Iterator_destroy( &iter->Iterator );
0535 iter = iter->previous;
0536 }
0537
0538 _User_extensions_Release( &lock_context );
0539 }
0540
0541
0542
0543
0544
0545 #ifdef __cplusplus
0546 }
0547 #endif
0548
0549 #endif
0550