source: rtems/cpukit/score/src/threadchangepriority.c @ e3f6d35

4.10
Last change on this file since e3f6d35 was b50468c, checked in by Gedare Bloom <gedare@…>, on 12/21/17 at 18:04:50

score: add Inherited_priorities priority queue and functions

Adds enqueue, dequeue, requeue, evaluate, and release functions
for the thread priority node priority queue of inherited priorities.
Add calls to these functions as needed to maintain the priority
queue due to blocking, unblocking, and priority changes.

Closes #3359.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*
2 *  Thread Handler / Change Priority
3 *
4 *  COPYRIGHT (c) 1989-2011.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <rtems/system.h>
19#include <rtems/score/apiext.h>
20#include <rtems/score/context.h>
21#include <rtems/score/interr.h>
22#include <rtems/score/isr.h>
23#include <rtems/score/object.h>
24#include <rtems/score/priority.h>
25#include <rtems/score/states.h>
26#include <rtems/score/sysstate.h>
27#include <rtems/score/thread.h>
28#include <rtems/score/threadq.h>
29#include <rtems/score/userext.h>
30#include <rtems/score/wkspace.h>
31
32/*PAGE
33 *
34 *  _Thread_Change_priority
35 *
36 *  This kernel routine changes the priority of the thread.  The
37 *  thread chain is adjusted if necessary.
38 *
39 *  Input parameters:
40 *    the_thread   - pointer to thread control block
41 *    new_priority - ultimate priority
42 *    prepend_it   - true if the thread should be prepended to the chain
43 *
44 *  Output parameters:  NONE
45 *
46 *  INTERRUPT LATENCY:
47 *    ready chain
48 *    select heir
49 */
50
51void _Thread_Change_priority(
52  Thread_Control   *the_thread,
53  Priority_Control  new_priority,
54  bool              prepend_it
55)
56{
57  ISR_Level      level;
58  States_Control state, original_state;
59
60  /*
61   *  If this is a case where prepending the task to its priority is
62   *  potentially desired, then we need to consider whether to do it.
63   *  This usually occurs when a task lowers its priority implcitly as
64   *  the result of losing inherited priority.  Normal explicit priority
65   *  change calls (e.g. rtems_task_set_priority) should always do an
66   *  append not a prepend.
67   */
68/*
69  if ( prepend_it &&
70       _Thread_Is_executing( the_thread ) &&
71       new_priority >= the_thread->Priority_node.current_priority )
72    prepend_it = true;
73*/
74
75  /*
76   * Save original state
77   */
78  original_state = the_thread->current_state;
79
80  /*
81   * Set a transient state for the thread so it is pulled off the Ready chains.
82   * This will prevent it from being scheduled no matter what happens in an
83   * ISR.
84   */
85  _Thread_Set_transient( the_thread );
86
87  /*
88   *  Do not bother recomputing all the priority related information if
89   *  we are not REALLY changing priority.
90   */
91  if ( the_thread->Priority_node.current_priority != new_priority ) {
92    _Thread_Set_priority( the_thread, new_priority );
93    _Thread_Requeue_priority_node( the_thread );
94  }
95
96  _ISR_Disable( level );
97
98  /*
99   *  If the thread has more than STATES_TRANSIENT set, then it is blocked,
100   *  If it is blocked on a thread queue, then we need to requeue it.
101   */
102  state = the_thread->current_state;
103  if ( state != STATES_TRANSIENT ) {
104    /* Only clear the transient state if it wasn't set already */
105    if ( ! _States_Is_transient( original_state ) )
106      the_thread->current_state = _States_Clear( STATES_TRANSIENT, state );
107    _ISR_Enable( level );
108    if ( _States_Is_waiting_on_thread_queue( state ) ) {
109      _Thread_queue_Requeue( the_thread->Wait.queue, the_thread );
110    }
111    return;
112  }
113
114  /* Only clear the transient state if it wasn't set already */
115  if ( ! _States_Is_transient( original_state ) ) {
116    /*
117     *  Interrupts are STILL disabled.
118     *  We now know the thread will be in the READY state when we remove
119     *  the TRANSIENT state.  So we have to place it on the appropriate
120     *  Ready Queue with interrupts off.
121     */
122    the_thread->current_state = _States_Clear( STATES_TRANSIENT, state );
123
124    _Priority_Add_to_bit_map( &the_thread->Priority_map );
125    if ( prepend_it )
126      _Chain_Prepend_unprotected( the_thread->ready, &the_thread->Object.Node );
127    else
128      _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node );
129  }
130
131  _ISR_Flash( level );
132
133  /*
134   *  We altered the set of thread priorities.  So let's figure out
135   *  who is the heir and if we need to switch to them.
136   */
137  _Thread_Calculate_heir();
138
139  if ( !_Thread_Is_executing_also_the_heir() &&
140       _Thread_Executing->is_preemptible )
141    _Context_Switch_necessary = true;
142  _ISR_Enable( level );
143}
Note: See TracBrowser for help on using the repository browser.