source: rtems/cpukit/rtems/src/tasksetpriority.c @ b20b736

5
Last change on this file since b20b736 was b20b736, checked in by Sebastian Huber <sebastian.huber@…>, on 06/28/16 at 04:54:50

score: Introduce _Thread_Get_priority()

Avoid direct access to thread internal data fields.

  • Property mode set to 100644
File size: 3.2 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief RTEMS Set Task Priority
5 *  @ingroup ClassicTasks
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2014.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/rtems/tasksimpl.h>
22#include <rtems/score/schedulerimpl.h>
23#include <rtems/score/threadimpl.h>
24
25typedef struct {
26  const Scheduler_Control *scheduler;
27  rtems_task_priority      new_priority;
28  Priority_Control         old_priority;
29  rtems_status_code        status;
30} RTEMS_tasks_Set_priority_context;
31
32static bool _RTEMS_tasks_Set_priority_filter(
33  Thread_Control   *the_thread,
34  Priority_Control *new_priority_p,
35  void             *arg
36)
37{
38  RTEMS_tasks_Set_priority_context *context;
39  const Scheduler_Control          *scheduler;
40  bool                              valid;
41  Priority_Control                  current_priority;
42  Priority_Control                  new_priority;
43
44  context = arg;
45  scheduler = _Scheduler_Get_own( the_thread );
46  current_priority = _Thread_Get_priority( the_thread );
47
48  context->scheduler = scheduler;
49  context->old_priority = current_priority;
50
51  new_priority = _RTEMS_Priority_To_core(
52    scheduler,
53    context->new_priority,
54    &valid
55  );
56
57  *new_priority_p = new_priority;
58
59  if ( !valid ) {
60    context->status = RTEMS_INVALID_PRIORITY;
61    return false;
62  }
63
64  the_thread->real_priority = new_priority;
65  context->status = STATUS_SUCCESSFUL;
66
67  return _Thread_Priority_less_than( current_priority, new_priority )
68    || !_Thread_Owns_resources( the_thread );
69}
70
71rtems_status_code rtems_task_set_priority(
72  rtems_id             id,
73  rtems_task_priority  new_priority,
74  rtems_task_priority *old_priority_p
75)
76{
77  Thread_Control          *the_thread;
78  ISR_lock_Context         lock_context;
79  const Scheduler_Control *scheduler;
80  Priority_Control         old_priority;
81  rtems_status_code        status;
82
83  if ( old_priority_p == NULL ) {
84    return RTEMS_INVALID_ADDRESS;
85  }
86
87  the_thread = _Thread_Get( id, &lock_context );
88
89  if ( the_thread == NULL ) {
90#if defined(RTEMS_MULTIPROCESSING)
91    return _RTEMS_tasks_MP_Set_priority( id, new_priority, old_priority_p );
92#else
93    return RTEMS_INVALID_ID;
94#endif
95  }
96
97  if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
98    RTEMS_tasks_Set_priority_context  context;
99    Per_CPU_Control                  *cpu_self;
100
101    cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
102    _ISR_lock_ISR_enable( &lock_context );
103
104    context.new_priority = new_priority;
105    _Thread_Change_priority(
106      the_thread,
107      0,
108      &context,
109      _RTEMS_tasks_Set_priority_filter,
110      false
111    );
112
113    _Thread_Dispatch_enable( cpu_self );
114    scheduler = context.scheduler;
115    old_priority = context.old_priority;
116    status = context.status;
117  } else {
118    _Thread_State_acquire_critical( the_thread, &lock_context );
119    scheduler = _Scheduler_Get_own( the_thread );
120    old_priority = _Thread_Get_priority( the_thread );
121    _Thread_State_release( the_thread, &lock_context );
122    status = RTEMS_SUCCESSFUL;
123  }
124
125  *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
126  return status;
127}
Note: See TracBrowser for help on using the repository browser.