File indexing completed on 2025-05-11 08:24:12
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_COREMUTEXIMPL_H
0039 #define _RTEMS_SCORE_COREMUTEXIMPL_H
0040
0041 #include <rtems/score/coremutex.h>
0042 #include <rtems/score/chainimpl.h>
0043 #include <rtems/score/schedulerimpl.h>
0044 #include <rtems/score/status.h>
0045 #include <rtems/score/threadimpl.h>
0046 #include <rtems/score/threadqimpl.h>
0047
0048 #ifdef __cplusplus
0049 extern "C" {
0050 #endif
0051
0052
0053
0054
0055
0056
0057
0058 #define CORE_MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
0059
0060 #define CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS \
0061 &_Thread_queue_Operations_priority_inherit
0062
0063
0064
0065
0066
0067
0068 static inline void _CORE_mutex_Initialize(
0069 CORE_mutex_Control *the_mutex
0070 )
0071 {
0072 _Thread_queue_Object_initialize( &the_mutex->Wait_queue );
0073 }
0074
0075
0076
0077
0078
0079
0080 static inline void _CORE_mutex_Destroy( CORE_mutex_Control *the_mutex )
0081 {
0082 _Thread_queue_Destroy( &the_mutex->Wait_queue );
0083 }
0084
0085
0086
0087
0088
0089
0090
0091 static inline void _CORE_mutex_Acquire_critical(
0092 CORE_mutex_Control *the_mutex,
0093 Thread_queue_Context *queue_context
0094 )
0095 {
0096 _Thread_queue_Acquire_critical( &the_mutex->Wait_queue, queue_context );
0097 }
0098
0099
0100
0101
0102
0103
0104
0105 static inline void _CORE_mutex_Release(
0106 CORE_mutex_Control *the_mutex,
0107 Thread_queue_Context *queue_context
0108 )
0109 {
0110 _Thread_queue_Release( &the_mutex->Wait_queue, queue_context );
0111 }
0112
0113
0114
0115
0116
0117
0118
0119
0120 static inline Thread_Control *_CORE_mutex_Get_owner(
0121 const CORE_mutex_Control *the_mutex
0122 )
0123 {
0124 return the_mutex->Wait_queue.Queue.owner;
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 static inline bool _CORE_mutex_Is_locked(
0139 const CORE_mutex_Control *the_mutex
0140 )
0141 {
0142 return _CORE_mutex_Get_owner( the_mutex ) != NULL;
0143 }
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 Status_Control _CORE_mutex_Seize_slow(
0158 CORE_mutex_Control *the_mutex,
0159 const Thread_queue_Operations *operations,
0160 Thread_Control *executing,
0161 bool wait,
0162 Thread_queue_Context *queue_context
0163 );
0164
0165
0166
0167
0168
0169
0170
0171 static inline void _CORE_mutex_Set_owner(
0172 CORE_mutex_Control *the_mutex,
0173 Thread_Control *owner
0174 )
0175 {
0176 the_mutex->Wait_queue.Queue.owner = owner;
0177 }
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 static inline bool _CORE_mutex_Is_owner(
0189 const CORE_mutex_Control *the_mutex,
0190 const Thread_Control *the_thread
0191 )
0192 {
0193 return _CORE_mutex_Get_owner( the_mutex ) == the_thread;
0194 }
0195
0196
0197
0198
0199
0200
0201 static inline void _CORE_recursive_mutex_Initialize(
0202 CORE_recursive_mutex_Control *the_mutex
0203 )
0204 {
0205 _CORE_mutex_Initialize( &the_mutex->Mutex );
0206 the_mutex->nest_level = 0;
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216 static inline Status_Control _CORE_recursive_mutex_Seize_nested(
0217 CORE_recursive_mutex_Control *the_mutex
0218 )
0219 {
0220 ++the_mutex->nest_level;
0221 return STATUS_SUCCESSFUL;
0222 }
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 static inline Status_Control _CORE_recursive_mutex_Seize(
0240 CORE_recursive_mutex_Control *the_mutex,
0241 const Thread_queue_Operations *operations,
0242 Thread_Control *executing,
0243 bool wait,
0244 Status_Control ( *nested )( CORE_recursive_mutex_Control * ),
0245 Thread_queue_Context *queue_context
0246 )
0247 {
0248 Thread_Control *owner;
0249
0250 _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
0251
0252 owner = _CORE_mutex_Get_owner( &the_mutex->Mutex );
0253
0254 if ( owner == NULL ) {
0255 _CORE_mutex_Set_owner( &the_mutex->Mutex, executing );
0256 _Thread_Resource_count_increment( executing );
0257 _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
0258 return STATUS_SUCCESSFUL;
0259 }
0260
0261 if ( owner == executing ) {
0262 Status_Control status;
0263
0264 status = ( *nested )( the_mutex );
0265 _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
0266 return status;
0267 }
0268
0269 return _CORE_mutex_Seize_slow(
0270 &the_mutex->Mutex,
0271 operations,
0272 executing,
0273 wait,
0274 queue_context
0275 );
0276 }
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289 static inline Status_Control _CORE_recursive_mutex_Surrender(
0290 CORE_recursive_mutex_Control *the_mutex,
0291 const Thread_queue_Operations *operations,
0292 Thread_Control *executing,
0293 Thread_queue_Context *queue_context
0294 )
0295 {
0296 unsigned int nest_level;
0297 Thread_queue_Heads *heads;
0298
0299 _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
0300
0301 if ( !_CORE_mutex_Is_owner( &the_mutex->Mutex, executing ) ) {
0302 _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
0303 return STATUS_NOT_OWNER;
0304 }
0305
0306 nest_level = the_mutex->nest_level;
0307
0308 if ( nest_level > 0 ) {
0309 the_mutex->nest_level = nest_level - 1;
0310 _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
0311 return STATUS_SUCCESSFUL;
0312 }
0313
0314 _Thread_Resource_count_decrement( executing );
0315 _CORE_mutex_Set_owner( &the_mutex->Mutex, NULL );
0316
0317 heads = the_mutex->Mutex.Wait_queue.Queue.heads;
0318
0319 if ( heads == NULL ) {
0320 _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
0321 return STATUS_SUCCESSFUL;
0322 }
0323
0324 _Thread_queue_Surrender(
0325 &the_mutex->Mutex.Wait_queue.Queue,
0326 heads,
0327 executing,
0328 queue_context,
0329 operations
0330 );
0331 return STATUS_SUCCESSFUL;
0332 }
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342 static inline void _CORE_ceiling_mutex_Initialize(
0343 CORE_ceiling_mutex_Control *the_mutex,
0344 const Scheduler_Control *scheduler,
0345 Priority_Control priority_ceiling
0346 )
0347 {
0348 _CORE_recursive_mutex_Initialize( &the_mutex->Recursive );
0349 _Priority_Node_initialize( &the_mutex->Priority_ceiling, priority_ceiling );
0350 #if defined(RTEMS_SMP)
0351 the_mutex->scheduler = scheduler;
0352 #endif
0353 }
0354
0355
0356
0357
0358
0359
0360
0361
0362 static inline const Scheduler_Control *
0363 _CORE_ceiling_mutex_Get_scheduler(
0364 const CORE_ceiling_mutex_Control *the_mutex
0365 )
0366 {
0367 #if defined(RTEMS_SMP)
0368 return the_mutex->scheduler;
0369 #else
0370 return &_Scheduler_Table[ 0 ];
0371 #endif
0372 }
0373
0374
0375
0376
0377
0378
0379
0380 static inline void _CORE_ceiling_mutex_Set_priority(
0381 CORE_ceiling_mutex_Control *the_mutex,
0382 Priority_Control priority_ceiling
0383 )
0384 {
0385 Thread_Control *owner;
0386
0387 owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
0388
0389 if ( owner != NULL ) {
0390 Thread_queue_Context queue_context;
0391
0392 _Thread_queue_Context_initialize( &queue_context );
0393 _Thread_queue_Context_clear_priority_updates( &queue_context );
0394 _Thread_Wait_acquire_critical( owner, &queue_context );
0395 _Thread_Priority_change(
0396 owner,
0397 &the_mutex->Priority_ceiling,
0398 priority_ceiling,
0399 PRIORITY_GROUP_LAST,
0400 &queue_context
0401 );
0402 _Thread_Wait_release_critical( owner, &queue_context );
0403 } else {
0404 the_mutex->Priority_ceiling.priority = priority_ceiling;
0405 }
0406 }
0407
0408
0409
0410
0411
0412
0413
0414
0415 static inline Priority_Control _CORE_ceiling_mutex_Get_priority(
0416 const CORE_ceiling_mutex_Control *the_mutex
0417 )
0418 {
0419 return the_mutex->Priority_ceiling.priority;
0420 }
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433 static inline Status_Control _CORE_ceiling_mutex_Set_owner(
0434 CORE_ceiling_mutex_Control *the_mutex,
0435 Thread_Control *owner,
0436 Thread_queue_Context *queue_context
0437 )
0438 {
0439 ISR_lock_Context lock_context;
0440 Scheduler_Node *scheduler_node;
0441 Per_CPU_Control *cpu_self;
0442
0443 _Thread_Wait_acquire_default_critical( owner, &lock_context );
0444
0445 scheduler_node = _Thread_Scheduler_get_home_node( owner );
0446
0447 if (
0448 _Priority_Get_priority( &scheduler_node->Wait.Priority )
0449 < the_mutex->Priority_ceiling.priority
0450 ) {
0451 _Thread_Wait_release_default_critical( owner, &lock_context );
0452 _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
0453 return STATUS_MUTEX_CEILING_VIOLATED;
0454 }
0455
0456 _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, owner );
0457 _Thread_Resource_count_increment( owner );
0458 _Thread_Priority_add(
0459 owner,
0460 &the_mutex->Priority_ceiling,
0461 queue_context
0462 );
0463 _Thread_Wait_release_default_critical( owner, &lock_context );
0464
0465 cpu_self = _Thread_queue_Dispatch_disable( queue_context );
0466 _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
0467 _Thread_Priority_update( queue_context );
0468 _Thread_Dispatch_enable( cpu_self );
0469 return STATUS_SUCCESSFUL;
0470 }
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487 static inline Status_Control _CORE_ceiling_mutex_Seize(
0488 CORE_ceiling_mutex_Control *the_mutex,
0489 Thread_Control *executing,
0490 bool wait,
0491 Status_Control ( *nested )( CORE_recursive_mutex_Control * ),
0492 Thread_queue_Context *queue_context
0493 )
0494 {
0495 Thread_Control *owner;
0496
0497 _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
0498
0499 #if defined(RTEMS_SMP)
0500 if (
0501 _Thread_Scheduler_get_home( executing )
0502 != _CORE_ceiling_mutex_Get_scheduler( the_mutex )
0503 ) {
0504 _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
0505 return STATUS_NOT_DEFINED;
0506 }
0507 #endif
0508
0509 owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
0510
0511 if ( owner == NULL ) {
0512 _Thread_queue_Context_clear_priority_updates( queue_context );
0513 return _CORE_ceiling_mutex_Set_owner(
0514 the_mutex,
0515 executing,
0516 queue_context
0517 );
0518 }
0519
0520 if ( owner == executing ) {
0521 Status_Control status;
0522
0523 status = ( *nested )( &the_mutex->Recursive );
0524 _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
0525 return status;
0526 }
0527
0528 return _CORE_mutex_Seize_slow(
0529 &the_mutex->Recursive.Mutex,
0530 CORE_MUTEX_TQ_OPERATIONS,
0531 executing,
0532 wait,
0533 queue_context
0534 );
0535 }
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547 static inline Status_Control _CORE_ceiling_mutex_Surrender(
0548 CORE_ceiling_mutex_Control *the_mutex,
0549 Thread_Control *executing,
0550 Thread_queue_Context *queue_context
0551 )
0552 {
0553 unsigned int nest_level;
0554
0555 _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
0556
0557 if ( !_CORE_mutex_Is_owner( &the_mutex->Recursive.Mutex, executing ) ) {
0558 _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
0559 return STATUS_NOT_OWNER;
0560 }
0561
0562 nest_level = the_mutex->Recursive.nest_level;
0563
0564 if ( nest_level > 0 ) {
0565 the_mutex->Recursive.nest_level = nest_level - 1;
0566 _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
0567 return STATUS_SUCCESSFUL;
0568 }
0569
0570 return _Thread_queue_Surrender_priority_ceiling(
0571 &the_mutex->Recursive.Mutex.Wait_queue.Queue,
0572 executing,
0573 &the_mutex->Priority_ceiling,
0574 queue_context,
0575 CORE_MUTEX_TQ_OPERATIONS
0576 );
0577 }
0578
0579
0580
0581 #ifdef __cplusplus
0582 }
0583 #endif
0584
0585 #endif
0586