source: rtems/cpukit/rtems/src/semsetpriority.c @ 66cb142

Last change on this file since 66cb142 was db3a3de, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 10, 2017 at 8:03:48 AM

score: Add _Thread_queue_Dispatch_disable()

  • Property mode set to 100644
File size: 4.2 KB
Line 
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#if HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/rtems/semimpl.h>
20#include <rtems/rtems/tasksimpl.h>
21#include <rtems/score/schedulerimpl.h>
22
23static 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
37static 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{
45  rtems_status_code  sc;
46  bool               valid;
47  Priority_Control   core_priority;
48  Priority_Control   old_priority;
49  Per_CPU_Control   *cpu_self;
50
51  core_priority = _RTEMS_Priority_To_core( scheduler, new_priority, &valid );
52  if ( new_priority != RTEMS_CURRENT_PRIORITY && !valid ) {
53    _ISR_lock_ISR_enable( &queue_context->Lock_context.Lock_context );
54    return RTEMS_INVALID_PRIORITY;
55  }
56
57  _Thread_queue_Context_clear_priority_updates( queue_context );
58  _Thread_queue_Acquire_critical(
59    &the_semaphore->Core_control.Wait_queue,
60    queue_context
61  );
62
63  switch ( the_semaphore->variant ) {
64    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
65      sc = _Semaphore_Is_scheduler_valid(
66        &the_semaphore->Core_control.Mutex,
67        scheduler
68      );
69
70      old_priority = _CORE_ceiling_mutex_Get_priority(
71        &the_semaphore->Core_control.Mutex
72      );
73
74      if ( sc == RTEMS_SUCCESSFUL && new_priority != RTEMS_CURRENT_PRIORITY ) {
75        _CORE_ceiling_mutex_Set_priority(
76          &the_semaphore->Core_control.Mutex,
77          core_priority,
78          queue_context
79        );
80      }
81
82      break;
83#if defined(RTEMS_SMP)
84    case SEMAPHORE_VARIANT_MRSP:
85      old_priority = _MRSP_Get_priority(
86        &the_semaphore->Core_control.MRSP,
87        scheduler
88      );
89
90      if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
91        _MRSP_Set_priority(
92          &the_semaphore->Core_control.MRSP,
93          scheduler,
94          core_priority
95        );
96      }
97
98      sc = RTEMS_SUCCESSFUL;
99      break;
100#endif
101    default:
102      _Assert(
103        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY
104          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
105          || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
106          || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
107      );
108      old_priority = 0;
109      sc = RTEMS_NOT_DEFINED;
110      break;
111  }
112
113  cpu_self = _Thread_queue_Dispatch_disable( queue_context );
114  _Thread_queue_Release(
115    &the_semaphore->Core_control.Wait_queue,
116    queue_context
117  );
118  _Thread_Priority_update( queue_context );
119  _Thread_Dispatch_enable( cpu_self );
120
121  *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
122  return sc;
123}
124
125rtems_status_code rtems_semaphore_set_priority(
126  rtems_id             semaphore_id,
127  rtems_id             scheduler_id,
128  rtems_task_priority  new_priority,
129  rtems_task_priority *old_priority
130)
131{
132  const Scheduler_Control *scheduler;
133  Semaphore_Control       *the_semaphore;
134  Thread_queue_Context     queue_context;
135
136  if ( old_priority == NULL ) {
137    return RTEMS_INVALID_ADDRESS;
138  }
139
140  scheduler = _Scheduler_Get_by_id( scheduler_id );
141  if ( scheduler == NULL ) {
142    return RTEMS_INVALID_ID;
143  }
144
145  the_semaphore = _Semaphore_Get( semaphore_id, &queue_context );
146
147  if ( the_semaphore == NULL ) {
148#if defined(RTEMS_MULTIPROCESSING)
149    if ( _Semaphore_MP_Is_remote( semaphore_id ) ) {
150      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
151    }
152#endif
153
154    return RTEMS_INVALID_ID;
155  }
156
157  return _Semaphore_Set_priority(
158    the_semaphore,
159    scheduler,
160    new_priority,
161    old_priority,
162    &queue_context
163  );
164}
Note: See TracBrowser for help on using the repository browser.