source: rtems/cpukit/rtems/src/semcreate.c @ 5a598ac

5
Last change on this file since 5a598ac was 5a598ac, checked in by Sebastian Huber <sebastian.huber@…>, on 05/27/16 at 06:02:03

score: Add CORE mutex variants

Add CORE_recursive_mutex_Control and CORE_ceiling_mutex_Control to avoid
the run-time evaluation of attributes to figure out how a particular
mutex methods should behave. Start with the no protocol variants. This
eliminates the CORE_MUTEX_DISCIPLINES_FIFO and
CORE_MUTEX_DISCIPLINES_PRIORITY disciplines.

  • Property mode set to 100644
File size: 6.9 KB
Line 
1/**
2 * @file
3 *
4 * @brief rtems_semaphore_create
5 * @ingroup ClassicSem Semaphores
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/system.h>
22#include <rtems/rtems/status.h>
23#include <rtems/rtems/support.h>
24#include <rtems/rtems/attrimpl.h>
25#include <rtems/score/isr.h>
26#include <rtems/rtems/options.h>
27#include <rtems/rtems/semimpl.h>
28#include <rtems/rtems/statusimpl.h>
29#include <rtems/rtems/tasksimpl.h>
30#include <rtems/score/coremuteximpl.h>
31#include <rtems/score/coresemimpl.h>
32#include <rtems/score/threaddispatch.h>
33#include <rtems/score/sysstate.h>
34
35#include <rtems/score/interr.h>
36
37/*
38 *  rtems_semaphore_create
39 *
40 *  This directive creates a semaphore and sets the initial value based
41 *  on the given count.  A semaphore id is returned.
42 *
43 *  Input parameters:
44 *    name             - user defined semaphore name
45 *    count            - initial count of semaphore
46 *    attribute_set    - semaphore attributes
47 *    priority_ceiling - semaphore's ceiling priority
48 *    id               - pointer to semaphore id
49 *
50 *  Output parameters:
51 *    id       - semaphore id
52 *    RTEMS_SUCCESSFUL - if successful
53 *    error code - if unsuccessful
54 */
55
56rtems_status_code rtems_semaphore_create(
57  rtems_name           name,
58  uint32_t             count,
59  rtems_attribute      attribute_set,
60  rtems_task_priority  priority_ceiling,
61  rtems_id            *id
62)
63{
64  Semaphore_Control     *the_semaphore;
65  CORE_mutex_Attributes  the_mutex_attr;
66  Thread_Control        *executing;
67  Status_Control         status;
68
69  if ( !rtems_is_name_valid( name ) )
70    return RTEMS_INVALID_NAME;
71
72  if ( !id )
73    return RTEMS_INVALID_ADDRESS;
74
75#if defined(RTEMS_MULTIPROCESSING)
76  if ( _Attributes_Is_global( attribute_set ) ) {
77
78    if ( !_System_state_Is_multiprocessing )
79      return RTEMS_MP_NOT_CONFIGURED;
80
81    if ( _Attributes_Is_inherit_priority( attribute_set ) ||
82         _Attributes_Is_priority_ceiling( attribute_set ) ||
83         _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) )
84      return RTEMS_NOT_DEFINED;
85
86  } else
87#endif
88
89  if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) &&
90       !( _Attributes_Is_binary_semaphore( attribute_set ) &&
91         !_Attributes_Is_priority( attribute_set ) ) ) {
92    return RTEMS_NOT_DEFINED;
93  }
94
95  if ( _Attributes_Is_inherit_priority( attribute_set ) ||
96              _Attributes_Is_priority_ceiling( attribute_set ) ) {
97
98    if ( ! (_Attributes_Is_binary_semaphore( attribute_set ) &&
99            _Attributes_Is_priority( attribute_set ) ) )
100      return RTEMS_NOT_DEFINED;
101
102  }
103
104  if ( !_Attributes_Has_at_most_one_protocol( attribute_set ) )
105    return RTEMS_NOT_DEFINED;
106
107  if ( !_Attributes_Is_counting_semaphore( attribute_set ) && ( count > 1 ) )
108    return RTEMS_INVALID_NUMBER;
109
110#if !defined(RTEMS_SMP)
111  /*
112   * On uni-processor configurations the Multiprocessor Resource Sharing
113   * Protocol is equivalent to the Priority Ceiling Protocol.
114   */
115  if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
116    attribute_set |= RTEMS_PRIORITY_CEILING | RTEMS_PRIORITY;
117  }
118#endif
119
120  the_semaphore = _Semaphore_Allocate();
121
122  if ( !the_semaphore ) {
123    _Objects_Allocator_unlock();
124    return RTEMS_TOO_MANY;
125  }
126
127#if defined(RTEMS_MULTIPROCESSING)
128  the_semaphore->is_global = _Attributes_Is_global( attribute_set );
129
130  if ( _Attributes_Is_global( attribute_set ) &&
131       ! ( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name,
132                            the_semaphore->Object.id, false ) ) ) {
133    _Semaphore_Free( the_semaphore );
134    _Objects_Allocator_unlock();
135    return RTEMS_TOO_MANY;
136  }
137#endif
138
139  the_semaphore->attribute_set = attribute_set;
140  executing = _Thread_Get_executing();
141
142  if ( _Attributes_Is_priority( attribute_set ) ) {
143    the_semaphore->discipline = SEMAPHORE_DISCIPLINE_PRIORITY;
144  } else {
145    the_semaphore->discipline = SEMAPHORE_DISCIPLINE_FIFO;
146  }
147
148  if ( _Attributes_Is_counting_semaphore( attribute_set ) ) {
149    the_semaphore->variant = SEMAPHORE_VARIANT_COUNTING;
150    _CORE_semaphore_Initialize(
151      &the_semaphore->Core_control.semaphore,
152      count
153    );
154    status = STATUS_SUCCESSFUL;
155  } else if ( _Attributes_Is_simple_binary_semaphore( attribute_set ) ) {
156    the_semaphore->variant = SEMAPHORE_VARIANT_SIMPLE_BINARY;
157    _CORE_semaphore_Initialize(
158      &the_semaphore->Core_control.semaphore,
159      count != 0
160    );
161    status = STATUS_SUCCESSFUL;
162#if defined(RTEMS_SMP)
163  } else if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
164    the_semaphore->variant = SEMAPHORE_VARIANT_MRSP;
165    status = _MRSP_Initialize(
166      &the_semaphore->Core_control.mrsp,
167      priority_ceiling,
168      executing,
169      count != 1
170    );
171#endif
172  } else if (
173    !_Attributes_Is_inherit_priority( attribute_set )
174      && !_Attributes_Is_priority_ceiling( attribute_set )
175  ) {
176    _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
177    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL;
178    _CORE_recursive_mutex_Initialize(
179      &the_semaphore->Core_control.Mutex.Recursive
180    );
181
182    if ( count == 0 ) {
183      _CORE_mutex_Set_owner(
184        &the_semaphore->Core_control.Mutex.Recursive.Mutex,
185        executing
186      );
187    }
188
189    status = STATUS_SUCCESSFUL;
190  } else {
191    _Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
192    the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX;
193
194    the_mutex_attr.priority_ceiling =
195      _RTEMS_tasks_Priority_to_Core( priority_ceiling );
196    the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
197
198    if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
199      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
200    } else {
201      _Assert( _Attributes_Is_priority_ceiling( attribute_set ) );
202      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
203    }
204
205    status = _CORE_mutex_Initialize(
206      &the_semaphore->Core_control.Mutex.Recursive.Mutex,
207      executing,
208      &the_mutex_attr,
209      count != 1
210    );
211  }
212
213  if ( status != STATUS_SUCCESSFUL ) {
214    _Semaphore_Free( the_semaphore );
215    _Objects_Allocator_unlock();
216    return _Status_Get( status );
217  }
218
219  /*
220   *  Whether we initialized it as a mutex or counting semaphore, it is
221   *  now ready to be "offered" for use as a Classic API Semaphore.
222   */
223  _Objects_Open(
224    &_Semaphore_Information,
225    &the_semaphore->Object,
226    (Objects_Name) name
227  );
228
229  *id = the_semaphore->Object.id;
230
231#if defined(RTEMS_MULTIPROCESSING)
232  if ( _Attributes_Is_global( attribute_set ) )
233    _Semaphore_MP_Send_process_packet(
234      SEMAPHORE_MP_ANNOUNCE_CREATE,
235      the_semaphore->Object.id,
236      name,
237      0                          /* Not used */
238    );
239#endif
240  _Objects_Allocator_unlock();
241  return RTEMS_SUCCESSFUL;
242}
Note: See TracBrowser for help on using the repository browser.