RTEMS
semsetpriority.c
1 /*
2  * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
3  *
4  * embedded brains GmbH
5  * Dornierstr. 4
6  * 82178 Puchheim
7  * Germany
8  * <rtems@embedded-brains.de>
9  *
10  * The license and distribution terms for this file may be
11  * found in the file LICENSE in this distribution or at
12  * http://www.rtems.org/license/LICENSE.
13  */
14 
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18 
19 #include <rtems/rtems/semimpl.h>
20 #include <rtems/rtems/tasksimpl.h>
22 
23 static rtems_status_code _Semaphore_Is_scheduler_valid(
24  const CORE_ceiling_mutex_Control *the_mutex,
25  const Scheduler_Control *scheduler
26 )
27 {
28 #if defined(RTEMS_SMP)
29  if ( scheduler != _CORE_ceiling_mutex_Get_scheduler( the_mutex ) ) {
30  return RTEMS_NOT_DEFINED;
31  }
32 #endif
33 
34  return RTEMS_SUCCESSFUL;
35 }
36 
37 static rtems_status_code _Semaphore_Set_priority(
38  Semaphore_Control *the_semaphore,
39  const Scheduler_Control *scheduler,
40  rtems_task_priority new_priority,
41  rtems_task_priority *old_priority_p,
42  Thread_queue_Context *queue_context
43 )
44 {
46  bool valid;
47  Priority_Control core_priority;
48  Priority_Control old_priority;
49  Per_CPU_Control *cpu_self;
50  Semaphore_Variant variant;
51 
52  core_priority = _RTEMS_Priority_To_core( scheduler, new_priority, &valid );
53  if ( new_priority != RTEMS_CURRENT_PRIORITY && !valid ) {
56  }
57 
60  &the_semaphore->Core_control.Wait_queue,
61  queue_context
62  );
63  variant = _Semaphore_Get_variant( _Semaphore_Get_flags( the_semaphore ) );
64 
65  switch ( variant ) {
66  case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
67  sc = _Semaphore_Is_scheduler_valid(
68  &the_semaphore->Core_control.Mutex,
69  scheduler
70  );
71 
72  old_priority = _CORE_ceiling_mutex_Get_priority(
73  &the_semaphore->Core_control.Mutex
74  );
75 
76  if ( sc == RTEMS_SUCCESSFUL && new_priority != RTEMS_CURRENT_PRIORITY ) {
78  &the_semaphore->Core_control.Mutex,
79  core_priority,
80  queue_context
81  );
82  }
83 
84  break;
85 #if defined(RTEMS_SMP)
86  case SEMAPHORE_VARIANT_MRSP:
87  old_priority = _MRSP_Get_priority(
88  &the_semaphore->Core_control.MRSP,
89  scheduler
90  );
91 
92  if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
94  &the_semaphore->Core_control.MRSP,
95  scheduler,
96  core_priority
97  );
98  }
99 
100  sc = RTEMS_SUCCESSFUL;
101  break;
102 #endif
103  default:
104  _Assert(
105  variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY
106  || variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
107  || variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
108  || variant == SEMAPHORE_VARIANT_COUNTING
109  );
110  old_priority = 0;
111  sc = RTEMS_NOT_DEFINED;
112  break;
113  }
114 
115  cpu_self = _Thread_queue_Dispatch_disable( queue_context );
117  &the_semaphore->Core_control.Wait_queue,
118  queue_context
119  );
120  _Thread_Priority_update( queue_context );
121  _Thread_Dispatch_enable( cpu_self );
122 
123  *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
124  return sc;
125 }
126 
128  rtems_id semaphore_id,
129  rtems_id scheduler_id,
130  rtems_task_priority new_priority,
131  rtems_task_priority *old_priority
132 )
133 {
134  const Scheduler_Control *scheduler;
135  Semaphore_Control *the_semaphore;
136  Thread_queue_Context queue_context;
137 
138  if ( old_priority == NULL ) {
139  return RTEMS_INVALID_ADDRESS;
140  }
141 
142  scheduler = _Scheduler_Get_by_id( scheduler_id );
143  if ( scheduler == NULL ) {
144  return RTEMS_INVALID_ID;
145  }
146 
147  the_semaphore = _Semaphore_Get( semaphore_id, &queue_context );
148 
149  if ( the_semaphore == NULL ) {
150 #if defined(RTEMS_MULTIPROCESSING)
151  if ( _Semaphore_MP_Is_remote( semaphore_id ) ) {
153  }
154 #endif
155 
156  return RTEMS_INVALID_ID;
157  }
158 
159  return _Semaphore_Set_priority(
160  the_semaphore,
161  scheduler,
162  new_priority,
163  old_priority,
164  &queue_context
165  );
166 }
static __inline__ void _Thread_queue_Acquire_critical(Thread_queue_Control *the_thread_queue, Thread_queue_Context *queue_context)
Acquires the thread queue control in a critical section.
Definition: threadqimpl.h:681
rtems_status_code rtems_semaphore_set_priority(rtems_id semaphore_id, rtems_id scheduler_id, rtems_task_priority new_priority, rtems_task_priority *old_priority)
%
#define RTEMS_CURRENT_PRIORITY
This constant is passed to {set-priority:/name}() when the caller wants to obtain the current priorit...
Definition: tasks.h:248
static __inline__ Priority_Control _RTEMS_Priority_To_core(const Scheduler_Control *scheduler, rtems_task_priority priority, bool *valid)
Converts the RTEMS API priority to the corresponding SuperCore priority and validates it...
Definition: tasksimpl.h:96
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:70
This status code indicates that an invalid thread priority was provided.
Definition: status.h:189
static __inline__ void _CORE_ceiling_mutex_Set_priority(CORE_ceiling_mutex_Control *the_mutex, Priority_Control priority_ceiling, Thread_queue_Context *queue_context)
Sets the priority of the ceiling mutex.
static __inline__ Per_CPU_Control * _Thread_queue_Dispatch_disable(Thread_queue_Context *queue_context)
Disables dispatching in a critical section.
Definition: threadqimpl.h:429
Thread queue context for the thread queue methods.
Definition: threadq.h:198
CORE_ceiling_mutex_Control Mutex
Definition: semdata.h:71
Inlined Routines Associated with the Manipulation of the Scheduler.
Thread_queue_Control Wait_queue
The thread queue present in all other variants.
Definition: semdata.h:65
#define _ISR_lock_ISR_enable(_context)
Restores the saved interrupt state of the ISR lock context.
Definition: isrlock.h:416
static __inline__ const Scheduler_Control * _CORE_ceiling_mutex_Get_scheduler(const CORE_ceiling_mutex_Control *the_mutex)
Gets the scheduler of the ceiling mutex.
static __inline__ Priority_Control _MRSP_Get_priority(const MRSP_Control *mrsp, const Scheduler_Control *scheduler)
Gets priority of the MrsP control.
Definition: mrspimpl.h:111
uint32_t rtems_task_priority
%
Definition: tasks.h:94
This status code indicates successful completion.
Definition: status.h:86
Classic Semaphore Manager Implementation.
rtems_status_code
This enumeration provides status codes for directives of the Classic API.
Definition: status.h:82
Per CPU Core Structure.
Definition: percpu.h:347
Thread_queue_Lock_context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:203
static __inline__ Priority_Control _CORE_ceiling_mutex_Get_priority(const CORE_ceiling_mutex_Control *the_mutex)
Gets the priority of the ceiling mutex.
void _Thread_Priority_update(Thread_queue_Context *queue_context)
Updates the priority of all threads in the set.
void _Thread_Dispatch_enable(Per_CPU_Control *cpu_self)
Enables thread dispatching.
static __inline__ void _Thread_queue_Context_clear_priority_updates(Thread_queue_Context *queue_context)
Clears the priority update count of the thread queue context.
Definition: threadqimpl.h:338
This status code indicates that a specified address was invalid.
Definition: status.h:133
This status code indicates that the item has not been initialized.
Definition: status.h:143
This status code indicates that an object identifier was invalid.
Definition: status.h:106
Objects_Id rtems_id
Values of this type identify an RTEMS object.
Definition: types.h:99
Scheduler control.
Definition: scheduler.h:264
This status code indicates that the operation was illegal on a remote object.
Definition: status.h:177
static __inline__ rtems_task_priority _RTEMS_Priority_From_core(const Scheduler_Control *scheduler, Priority_Control priority)
Converts the SuperCore priority to the corresponding RTEMS API priority.
Definition: tasksimpl.h:116
static __inline__ void _MRSP_Set_priority(MRSP_Control *mrsp, const Scheduler_Control *scheduler, Priority_Control new_priority)
Sets priority of the MrsP control.
Definition: mrspimpl.h:129
The recursive mutex control with priority ceiling protocol support.
Definition: coremutex.h:83
ISR_lock_Context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:130
void _Thread_queue_Release(Thread_queue_Control *the_thread_queue, Thread_queue_Context *queue_context)
Releases the thread queue control and enables interrupts.
Definition: threadq.c:118
union Semaphore_Control::@8 Core_control
Semaphore_Variant
Classic semaphore variants.
Definition: semimpl.h:42
static __inline__ const Scheduler_Control * _Scheduler_Get_by_id(Objects_Id id)
Gets the scheduler from the given object build id.
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
Definition: assert.h:100
Classic Tasks Manager Implementation.