Changeset dafa5d88 in rtems
- Timestamp:
- Sep 3, 2015, 8:27:16 AM (6 years ago)
- Branches:
- 5, master
- Children:
- e1769f27
- Parents:
- 3995e6d
- git-author:
- Sebastian Huber <sebastian.huber@…> (09/03/15 08:27:16)
- git-committer:
- Sebastian Huber <sebastian.huber@…> (09/04/15 11:26:17)
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/score/include/rtems/score/threadimpl.h
r3995e6d rdafa5d88 436 436 Priority_Control new_priority 437 437 ); 438 439 /** 440 * @brief Inherit the priority of a thread. 441 * 442 * It changes the current priority of the inheritor thread to the current priority 443 * of the ancestor thread if it is higher than the current priority of the inheritor 444 * thread. In this case the inheritor thread is appended to its new priority group 445 * in its scheduler instance. 446 * 447 * On SMP configurations, the priority is changed to PRIORITY_PSEUDO_ISR in 448 * case the own schedulers of the inheritor and ancestor thread differ (priority 449 * boosting). 450 * 451 * @param[in] inheritor The thread to inherit the priority. 452 * @param[in] ancestor The thread to bequeath its priority to the inheritor 453 * thread. 454 */ 455 #if defined(RTEMS_SMP) 456 void _Thread_Inherit_priority( 457 Thread_Control *inheritor, 458 Thread_Control *ancestor 459 ); 460 #else 461 RTEMS_INLINE_ROUTINE void _Thread_Inherit_priority( 462 Thread_Control *inheritor, 463 Thread_Control *ancestor 464 ) 465 { 466 _Thread_Raise_priority( inheritor, ancestor->current_priority ); 467 } 468 #endif 438 469 439 470 /** -
cpukit/score/include/rtems/score/threadqimpl.h
r3995e6d rdafa5d88 523 523 524 524 /** 525 * @brief Boosts the priority of the thread if threads of another scheduler 526 * instance are enqueued on the thread queue. 527 * 528 * The thread queue must use the priority waiting discipline. 529 * 530 * @param[in] queue The actual thread queue. 531 * @param[in] the_thread The thread to boost the priority if necessary. 532 */ 533 #if defined(RTEMS_SMP) 534 void _Thread_queue_Boost_priority( 535 Thread_queue_Queue *queue, 536 Thread_Control *the_thread 537 ); 538 #else 539 RTEMS_INLINE_ROUTINE void _Thread_queue_Boost_priority( 540 Thread_queue_Queue *queue, 541 Thread_Control *the_thread 542 ) 543 { 544 (void) queue; 545 (void) the_thread; 546 } 547 #endif 548 549 /** 525 550 * @brief Compare two thread's priority for RBTree Insertion. 526 551 * -
cpukit/score/src/coremutexseize.c
r3995e6d rdafa5d88 76 76 #endif 77 77 78 _Thread_ Raise_priority( holder, executing->current_priority);78 _Thread_Inherit_priority( holder, executing ); 79 79 80 80 #if !defined(RTEMS_SMP) -
cpukit/score/src/coremutexsurrender.c
r3995e6d rdafa5d88 210 210 _CORE_mutex_Push_priority( the_mutex, the_thread ); 211 211 the_thread->resource_count++; 212 _Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread ); 212 213 break; 213 214 case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING: -
cpukit/score/src/mutex.c
r3995e6d rdafa5d88 113 113 ) 114 114 { 115 /* Priority inheritance */ 116 _Thread_Raise_priority( owner, executing->current_priority ); 117 115 _Thread_Inherit_priority( owner, executing ); 118 116 _Thread_queue_Enqueue_critical( 119 117 &mutex->Queue.Queue, … … 137 135 if (heads != NULL) { 138 136 const Thread_queue_Operations *operations; 139 Thread_Control *first; 137 Thread_Control *first; 138 bool unblock; 140 139 141 140 operations = MUTEX_TQ_OPERATIONS; … … 143 142 144 143 mutex->owner = first; 145 _Thread_queue_Extract_critical(144 unblock = _Thread_queue_Extract_locked( 146 145 &mutex->Queue.Queue, 147 146 operations, 147 first 148 ); 149 _Thread_queue_Boost_priority( &mutex->Queue.Queue, first ); 150 _Thread_queue_Unblock_critical( 151 unblock, 152 &mutex->Queue.Queue, 148 153 first, 149 154 lock_context -
cpukit/score/src/threadchangepriority.c
r3995e6d rdafa5d88 111 111 } 112 112 113 #if defined(RTEMS_SMP) 114 static bool _Thread_Inherit_priority_filter( 115 Thread_Control *inheritor, 116 Priority_Control *new_priority, 117 void *arg 118 ) 119 { 120 Thread_Control *ancestor = arg; 121 122 if ( _Scheduler_Get_own( inheritor ) == _Scheduler_Get_own( ancestor ) ) { 123 *new_priority = ancestor->current_priority; 124 } 125 126 return _Thread_Priority_less_than( 127 inheritor->current_priority, 128 *new_priority 129 ); 130 } 131 132 void _Thread_Inherit_priority( 133 Thread_Control *inheritor, 134 Thread_Control *ancestor 135 ) 136 { 137 _Thread_Change_priority( 138 inheritor, 139 PRIORITY_PSEUDO_ISR, 140 ancestor, 141 _Thread_Inherit_priority_filter, 142 false 143 ); 144 } 145 #endif 146 113 147 static bool _Thread_Restore_priority_filter( 114 148 Thread_Control *the_thread, -
cpukit/score/src/threadqops.c
r3995e6d rdafa5d88 294 294 } 295 295 296 #if defined(RTEMS_SMP) 297 void _Thread_queue_Boost_priority( 298 Thread_queue_Queue *queue, 299 Thread_Control *the_thread 300 ) 301 { 302 Thread_queue_Heads *heads = queue->heads; 303 304 if ( 305 heads != NULL 306 && ( 307 !_Chain_Has_only_one_node( &heads->Heads.Fifo ) 308 || _RBTree_Is_empty( 309 &_Thread_queue_Priority_queue( heads, the_thread )->Queue 310 ) 311 ) 312 ) { 313 _Thread_Raise_priority( the_thread, PRIORITY_PSEUDO_ISR ); 314 } 315 } 316 #endif 317 296 318 const Thread_queue_Operations _Thread_queue_Operations_default = { 297 319 .priority_change = _Thread_queue_Do_nothing_priority_change, -
doc/user/glossary.texi
r3995e6d rdafa5d88 505 505 importance of an element in a set of items. RTEMS uses priority 506 506 to determine which task should execute. 507 508 @item priority boosting 509 A simple approach to extend the priority inheritance protocol for clustered 510 scheduling is @dfn{priority boosting}. In case a mutex is owned by a task of 511 another cluster, then the priority of the owner task is raised to an 512 artificially high priority, the pseudo-interrupt priority. 507 513 508 514 @item priority inheritance -
doc/user/sem.t
r3995e6d rdafa5d88 115 115 the resource, the task holding the resource may have its 116 116 priority increased. 117 118 On SMP configurations, in case the task holding the resource and the task that 119 blocks attempting to obtain the resource are in different scheduler instances, 120 the priority of the holder is raised to the pseudo-interrupt priority (priority 121 boosting). The pseudo-interrupt priority is the highest priority. 117 122 118 123 RTEMS supports priority inheritance for local, binary -
doc/user/smp.t
r3995e6d rdafa5d88 165 165 traffic. It is easy to implement. The problem is to provide synchronization 166 166 primitives for inter-cluster synchronization (more than one cluster is involved 167 in the synchronization process). In RTEMS there are currently threemeans167 in the synchronization process). In RTEMS there are currently four means 168 168 available 169 169 170 170 @itemize @bullet 171 171 @item events, 172 @item message queues, and 172 @item message queues, 173 @item semaphores using the @ref{Semaphore Manager Priority Inheritance} 174 protocol (priority boosting), and 173 175 @item semaphores using the @ref{Semaphore Manager Multiprocessor Resource 174 176 Sharing Protocol} (MrsP). -
testsuites/smptests/smpmutex01/init.c
r3995e6d rdafa5d88 27 27 #define PART_COUNT 2 28 28 29 #define TASK_COUNT 829 #define TASK_COUNT 9 30 30 31 31 typedef enum { … … 44 44 B_5_0, 45 45 B_5_1, 46 H, 46 H_A, 47 H_B, 47 48 NONE 48 49 } task_id; … … 112 113 } 113 114 114 static void sync_with_helper (test_context *ctx)115 static void sync_with_helper_by_id(test_context *ctx, task_id id) 115 116 { 116 117 rtems_event_set events; 117 118 118 send_event(ctx, H, REQ_WAKE_UP_HELPER);119 send_event(ctx, id, REQ_WAKE_UP_HELPER); 119 120 events = wait_for_events(); 120 121 rtems_test_assert(events == REQ_WAKE_UP_MASTER); 121 122 } 122 123 124 static void sync_with_helper(test_context *ctx) 125 { 126 sync_with_helper_by_id(ctx, H_A); 127 sync_with_helper_by_id(ctx, H_B); 128 } 129 123 130 static void request(test_context *ctx, task_id id, request_id req) 124 131 { … … 158 165 rtems_test_assert(ctx->generation[i] == ctx->expected_generation[i]); 159 166 } 167 } 168 169 static void assert_prio( 170 test_context *ctx, 171 task_id id, 172 rtems_task_priority expected 173 ) 174 { 175 rtems_task_priority actual; 176 rtems_status_code sc; 177 178 sc = rtems_task_set_priority( 179 ctx->tasks[id], 180 RTEMS_CURRENT_PRIORITY, 181 &actual 182 ); 183 rtems_test_assert(sc == RTEMS_SUCCESSFUL); 184 rtems_test_assert(expected == actual); 160 185 } 161 186 … … 203 228 start_task(ctx, B_5_0, worker, 5, SCHED_B); 204 229 start_task(ctx, B_5_1, worker, 5, SCHED_B); 205 start_task(ctx, H, helper, 6, SCHED_B); 230 start_task(ctx, H_A, helper, 3, SCHED_A); 231 start_task(ctx, H_B, helper, 6, SCHED_B); 206 232 207 233 sc = rtems_semaphore_create( … … 217 243 request(ctx, A_1, REQ_MTX_OBTAIN); 218 244 check_generations(ctx, NONE, NONE); 245 assert_prio(ctx, M, 1); 219 246 release(ctx); 220 247 check_generations(ctx, A_1, NONE); 248 assert_prio(ctx, M, 3); 221 249 request(ctx, A_1, REQ_MTX_RELEASE); 222 250 check_generations(ctx, A_1, NONE); … … 227 255 request(ctx, A_2_1, REQ_MTX_OBTAIN); 228 256 check_generations(ctx, NONE, NONE); 257 assert_prio(ctx, M, 1); 229 258 release(ctx); 230 259 check_generations(ctx, A_1, NONE); 260 assert_prio(ctx, M, 3); 261 assert_prio(ctx, A_1, 1); 231 262 request(ctx, A_1, REQ_MTX_RELEASE); 232 263 check_generations(ctx, A_1, A_2_0); … … 241 272 request(ctx, B_5_1, REQ_MTX_OBTAIN); 242 273 check_generations(ctx, NONE, NONE); 274 assert_prio(ctx, M, 0); 243 275 release(ctx); 244 276 sync_with_helper(ctx); 277 assert_prio(ctx, M, 3); 245 278 check_generations(ctx, B_4, NONE); 246 279 request(ctx, B_4, REQ_MTX_RELEASE); … … 253 286 obtain(ctx); 254 287 request(ctx, A_2_0, REQ_MTX_OBTAIN); 288 check_generations(ctx, NONE, NONE); 289 assert_prio(ctx, M, 2); 255 290 request(ctx, B_5_0, REQ_MTX_OBTAIN); 291 check_generations(ctx, NONE, NONE); 292 assert_prio(ctx, M, 0); 256 293 request(ctx, B_5_1, REQ_MTX_OBTAIN); 257 294 request(ctx, B_4, REQ_MTX_OBTAIN); … … 260 297 check_generations(ctx, NONE, NONE); 261 298 release(ctx); 299 sync_with_helper(ctx); 262 300 check_generations(ctx, A_1, NONE); 301 assert_prio(ctx, M, 3); 302 assert_prio(ctx, A_1, 0); 263 303 request(ctx, A_1, REQ_MTX_RELEASE); 264 304 check_generations(ctx, A_1, B_4); 305 assert_prio(ctx, A_1, 1); 306 assert_prio(ctx, B_4, 0); 265 307 request(ctx, B_4, REQ_MTX_RELEASE); 266 308 check_generations(ctx, B_4, A_2_0); 309 assert_prio(ctx, B_4, 4); 310 assert_prio(ctx, A_2_0, 0); 267 311 request(ctx, A_2_0, REQ_MTX_RELEASE); 268 312 check_generations(ctx, A_2_0, B_5_0); 313 assert_prio(ctx, A_2_0, 2); 314 assert_prio(ctx, B_5_0, 0); 269 315 request(ctx, B_5_0, REQ_MTX_RELEASE); 270 316 check_generations(ctx, B_5_0, A_2_1); 317 assert_prio(ctx, B_5_0, 5); 318 assert_prio(ctx, A_2_1, 0); 271 319 request(ctx, A_2_1, REQ_MTX_RELEASE); 272 320 check_generations(ctx, A_2_1, B_5_1); 321 assert_prio(ctx, A_2_1, 2); 322 assert_prio(ctx, B_5_1, 5); 273 323 request(ctx, B_5_1, REQ_MTX_RELEASE); 274 324 check_generations(ctx, B_5_1, NONE); 325 assert_prio(ctx, B_5_1, 5); 275 326 } 276 327
Note: See TracChangeset
for help on using the changeset viewer.