source: rtems/cpukit/rtems/src/semsetpriority.c @ f009ed0

5
Last change on this file since f009ed0 was f009ed0, checked in by Sebastian Huber <sebastian.huber@…>, on 04/27/16 at 14:36:04

rtems: Avoid Giant lock for semaphores

Update #2555.

  • Property mode set to 100644
File size: 3.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/attrimpl.h>
21#include <rtems/rtems/tasksimpl.h>
22#include <rtems/score/schedulerimpl.h>
23
24static rtems_status_code _Semaphore_Set_priority(
25  Semaphore_Control   *the_semaphore,
26  rtems_id             scheduler_id,
27  rtems_task_priority  new_priority,
28  rtems_task_priority *old_priority_p,
29  ISR_lock_Context    *lock_context
30)
31{
32  rtems_status_code   sc;
33  rtems_attribute     attribute_set = the_semaphore->attribute_set;
34  rtems_task_priority old_priority;
35
36  new_priority = _RTEMS_tasks_Priority_to_Core( new_priority );
37
38#if defined(RTEMS_SMP)
39  if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
40    MRSP_Control *mrsp = &the_semaphore->Core_control.mrsp;
41    uint32_t scheduler_index = _Scheduler_Get_index_by_id( scheduler_id );
42
43    _MRSP_Acquire_critical( mrsp, lock_context );
44
45    old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index );
46
47    if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
48      _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority );
49    }
50
51    _MRSP_Release( mrsp, lock_context );
52
53    sc = RTEMS_SUCCESSFUL;
54  } else
55#endif
56  if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
57    CORE_mutex_Control *mutex = &the_semaphore->Core_control.mutex;
58
59    _CORE_mutex_Acquire_critical( mutex, lock_context );
60
61    old_priority = mutex->Attributes.priority_ceiling;
62
63    if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
64      mutex->Attributes.priority_ceiling = new_priority;
65    }
66
67    _CORE_mutex_Release( mutex, lock_context );
68
69    sc = RTEMS_SUCCESSFUL;
70  } else {
71    _ISR_lock_ISR_enable( lock_context );
72
73    old_priority = 0;
74
75    sc = RTEMS_NOT_DEFINED;
76  }
77
78  *old_priority_p = _RTEMS_tasks_Priority_from_Core( old_priority );
79
80  return sc;
81}
82
83rtems_status_code rtems_semaphore_set_priority(
84  rtems_id             semaphore_id,
85  rtems_id             scheduler_id,
86  rtems_task_priority  new_priority,
87  rtems_task_priority *old_priority
88)
89{
90  Semaphore_Control *the_semaphore;
91  Objects_Locations  location;
92  ISR_lock_Context   lock_context;
93
94  if ( new_priority != RTEMS_CURRENT_PRIORITY &&
95       !_RTEMS_tasks_Priority_is_valid( new_priority ) ) {
96    return RTEMS_INVALID_PRIORITY;
97  }
98
99  if ( old_priority == NULL ) {
100    return RTEMS_INVALID_ADDRESS;
101  }
102
103  if ( !_Scheduler_Is_id_valid( scheduler_id ) ) {
104    return RTEMS_INVALID_ID;
105  }
106
107  the_semaphore = _Semaphore_Get_interrupt_disable(
108    semaphore_id,
109    &location,
110    &lock_context
111  );
112  switch ( location ) {
113    case OBJECTS_LOCAL:
114      return _Semaphore_Set_priority(
115        the_semaphore,
116        scheduler_id,
117        new_priority,
118        old_priority,
119        &lock_context
120      );
121#if defined(RTEMS_MULTIPROCESSING)
122    case OBJECTS_REMOTE:
123      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
124#endif
125    case OBJECTS_ERROR:
126      break;
127  }
128
129  return RTEMS_INVALID_ID;
130}
Note: See TracBrowser for help on using the repository browser.