source: rtems/cpukit/score/src/threadchangepriority.c @ 3a58dc8

5
Last change on this file since 3a58dc8 was 3a58dc8, checked in by Sebastian Huber <sebastian.huber@…>, on 07/05/16 at 11:37:10

score: Priority inherit thread queue operations

Move the priority change due to priority interitance to the thread queue
enqueue operation to simplify the locking on SMP configurations.

Update #2412.
Update #2556.
Update #2765.

  • Property mode set to 100644
File size: 3.9 KB
Line 
1/**
2 * @file
3 *
4 * @brief Changes the Priority of a Thread
5 *
6 * @ingroup ScoreThread
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2014.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#if HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include <rtems/score/threadimpl.h>
23#include <rtems/score/schedulerimpl.h>
24
25static Thread_Control *_Thread_Apply_priority_locked(
26  Thread_Control                *the_thread,
27  Priority_Control               new_priority,
28  void                          *arg,
29  Thread_Change_priority_filter  filter,
30  bool                           prepend_it
31)
32{
33  /*
34   * For simplicity set the priority restore hint unconditionally since this is
35   * an average case optimization.  Otherwise complicated atomic operations
36   * would be necessary.  Synchronize with a potential read of the resource
37   * count in the filter function.  See also _CORE_mutex_Surrender(),
38   * _Thread_Set_priority_filter() and _Thread_Restore_priority_filter().
39   */
40  the_thread->priority_restore_hint = true;
41  _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
42
43  /*
44   *  Do not bother recomputing all the priority related information if
45   *  we are not REALLY changing priority.
46   */
47  if ( ( *filter )( the_thread, &new_priority, arg ) ) {
48    Scheduler_Node *own_node;
49
50    own_node = _Scheduler_Thread_get_own_node( the_thread );
51    _Scheduler_Node_set_priority( own_node, new_priority, prepend_it );
52
53    the_thread->current_priority = new_priority;
54
55    ( *the_thread->Wait.operations->priority_change )(
56      the_thread,
57      new_priority,
58      the_thread->Wait.queue
59    );
60  } else {
61    the_thread = NULL;
62  }
63
64  return the_thread;
65}
66
67Thread_Control *_Thread_Apply_priority(
68  Thread_Control                *the_thread,
69  Priority_Control               new_priority,
70  void                          *arg,
71  Thread_Change_priority_filter  filter,
72  bool                           prepend_it
73)
74{
75  ISR_lock_Context  lock_context;
76  ISR_lock_Control *lock;
77
78  lock = _Thread_Lock_acquire( the_thread, &lock_context );
79  the_thread = _Thread_Apply_priority_locked(
80    the_thread,
81    new_priority,
82    arg,
83    filter,
84    prepend_it
85  );
86  _Thread_Lock_release( lock, &lock_context );
87  return the_thread;
88}
89
90void _Thread_Update_priority( Thread_Control *the_thread )
91{
92  if ( the_thread != NULL ) {
93    ISR_lock_Context lock_context;
94
95    _Thread_State_acquire( the_thread, &lock_context );
96    _Scheduler_Update_priority( the_thread );
97    _Thread_State_release( the_thread, &lock_context );
98  }
99}
100
101void _Thread_Change_priority(
102  Thread_Control                *the_thread,
103  Priority_Control               new_priority,
104  void                          *arg,
105  Thread_Change_priority_filter  filter,
106  bool                           prepend_it
107)
108{
109  the_thread = _Thread_Apply_priority(
110    the_thread,
111    new_priority,
112    arg,
113    filter,
114    prepend_it
115  );
116  _Thread_Update_priority( the_thread );
117}
118
119static bool _Thread_Raise_priority_filter(
120  Thread_Control   *the_thread,
121  Priority_Control *new_priority,
122  void             *arg
123)
124{
125  return _Thread_Priority_less_than(
126    the_thread->current_priority,
127    *new_priority
128  );
129}
130
131void _Thread_Raise_priority(
132  Thread_Control   *the_thread,
133  Priority_Control  new_priority
134)
135{
136  _Thread_Change_priority(
137    the_thread,
138    new_priority,
139    NULL,
140    _Thread_Raise_priority_filter,
141    false
142  );
143}
144
145static bool _Thread_Restore_priority_filter(
146  Thread_Control   *the_thread,
147  Priority_Control *new_priority,
148  void             *arg
149)
150{
151  *new_priority = the_thread->real_priority;
152
153  the_thread->priority_restore_hint = false;
154
155  return *new_priority != the_thread->current_priority;
156}
157
158void _Thread_Restore_priority( Thread_Control *the_thread )
159{
160  _Thread_Change_priority(
161    the_thread,
162    0,
163    NULL,
164    _Thread_Restore_priority_filter,
165    true
166  );
167}
Note: See TracBrowser for help on using the repository browser.