source: rtems/cpukit/rtems/src/semcreate.c @ ef6f8a83

5
Last change on this file since ef6f8a83 was 97bbf02, checked in by Sebastian Huber <sebastian.huber@…>, on 03/22/16 at 07:52:50

score: Use constant for maximum count of CORE sema

  • Property mode set to 100644
File size: 7.2 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/tasksimpl.h>
29#include <rtems/score/coremuteximpl.h>
30#include <rtems/score/coresemimpl.h>
31#include <rtems/score/threaddispatch.h>
32#include <rtems/score/sysstate.h>
33
34#include <rtems/score/interr.h>
35
36/*
37 *  rtems_semaphore_create
38 *
39 *  This directive creates a semaphore and sets the initial value based
40 *  on the given count.  A semaphore id is returned.
41 *
42 *  Input parameters:
43 *    name             - user defined semaphore name
44 *    count            - initial count of semaphore
45 *    attribute_set    - semaphore attributes
46 *    priority_ceiling - semaphore's ceiling priority
47 *    id               - pointer to semaphore id
48 *
49 *  Output parameters:
50 *    id       - semaphore id
51 *    RTEMS_SUCCESSFUL - if successful
52 *    error code - if unsuccessful
53 */
54
55rtems_status_code rtems_semaphore_create(
56  rtems_name           name,
57  uint32_t             count,
58  rtems_attribute      attribute_set,
59  rtems_task_priority  priority_ceiling,
60  rtems_id            *id
61)
62{
63  Semaphore_Control          *the_semaphore;
64  CORE_mutex_Attributes       the_mutex_attr;
65  CORE_semaphore_Disciplines  semaphore_discipline;
66  CORE_mutex_Status           mutex_status;
67
68  if ( !rtems_is_name_valid( name ) )
69    return RTEMS_INVALID_NAME;
70
71  if ( !id )
72    return RTEMS_INVALID_ADDRESS;
73
74#if defined(RTEMS_MULTIPROCESSING)
75  if ( _Attributes_Is_global( attribute_set ) ) {
76
77    if ( !_System_state_Is_multiprocessing )
78      return RTEMS_MP_NOT_CONFIGURED;
79
80    if ( _Attributes_Is_inherit_priority( attribute_set ) ||
81         _Attributes_Is_priority_ceiling( attribute_set ) ||
82         _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) )
83      return RTEMS_NOT_DEFINED;
84
85  } else
86#endif
87
88  if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) &&
89       !( _Attributes_Is_binary_semaphore( attribute_set ) &&
90         !_Attributes_Is_priority( attribute_set ) ) ) {
91    return RTEMS_NOT_DEFINED;
92  }
93
94  if ( _Attributes_Is_inherit_priority( attribute_set ) ||
95              _Attributes_Is_priority_ceiling( attribute_set ) ) {
96
97    if ( ! (_Attributes_Is_binary_semaphore( attribute_set ) &&
98            _Attributes_Is_priority( attribute_set ) ) )
99      return RTEMS_NOT_DEFINED;
100
101  }
102
103  if ( !_Attributes_Has_at_most_one_protocol( attribute_set ) )
104    return RTEMS_NOT_DEFINED;
105
106  if ( !_Attributes_Is_counting_semaphore( attribute_set ) && ( count > 1 ) )
107    return RTEMS_INVALID_NUMBER;
108
109#if !defined(RTEMS_SMP)
110  /*
111   * On uni-processor configurations the Multiprocessor Resource Sharing
112   * Protocol is equivalent to the Priority Ceiling Protocol.
113   */
114  if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
115    attribute_set |= RTEMS_PRIORITY_CEILING | RTEMS_PRIORITY;
116  }
117#endif
118
119  the_semaphore = _Semaphore_Allocate();
120
121  if ( !the_semaphore ) {
122    _Objects_Allocator_unlock();
123    return RTEMS_TOO_MANY;
124  }
125
126#if defined(RTEMS_MULTIPROCESSING)
127  if ( _Attributes_Is_global( attribute_set ) &&
128       ! ( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name,
129                            the_semaphore->Object.id, false ) ) ) {
130    _Semaphore_Free( the_semaphore );
131    _Objects_Allocator_unlock();
132    return RTEMS_TOO_MANY;
133  }
134#endif
135
136  the_semaphore->attribute_set = attribute_set;
137
138  /*
139   *  Initialize it as a counting semaphore.
140   */
141  if ( _Attributes_Is_counting_semaphore( attribute_set ) ) {
142    if ( _Attributes_Is_priority( attribute_set ) )
143      semaphore_discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY;
144    else
145      semaphore_discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
146
147    /*
148     *  The following are just to make Purify happy.
149     */
150    the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
151    the_mutex_attr.priority_ceiling = PRIORITY_MINIMUM;
152
153    _CORE_semaphore_Initialize(
154      &the_semaphore->Core_control.semaphore,
155      semaphore_discipline,
156      count
157    );
158#if defined(RTEMS_SMP)
159  } else if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
160    MRSP_Status mrsp_status = _MRSP_Initialize(
161      &the_semaphore->Core_control.mrsp,
162      priority_ceiling,
163      _Thread_Get_executing(),
164      count != 1
165    );
166
167    if ( mrsp_status != MRSP_SUCCESSFUL ) {
168      _Semaphore_Free( the_semaphore );
169      _Objects_Allocator_unlock();
170
171      return _Semaphore_Translate_MRSP_status_code( mrsp_status );
172    }
173#endif
174  } else {
175    /*
176     *  It is either simple binary semaphore or a more powerful mutex
177     *  style binary semaphore.  This is the mutex style.
178     */
179    if ( _Attributes_Is_priority( attribute_set ) )
180      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY;
181    else
182      the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
183
184    if ( _Attributes_Is_binary_semaphore( attribute_set ) ) {
185      the_mutex_attr.priority_ceiling      = _RTEMS_tasks_Priority_to_Core(
186                                               priority_ceiling
187                                             );
188      the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
189      the_mutex_attr.only_owner_release    = false;
190
191      if ( the_mutex_attr.discipline == CORE_MUTEX_DISCIPLINES_PRIORITY ) {
192        if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
193          the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
194          the_mutex_attr.only_owner_release = true;
195        } else if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
196          the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
197          the_mutex_attr.only_owner_release = true;
198        }
199      }
200    } else /* must be simple binary semaphore */ {
201      the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_BLOCKS;
202      the_mutex_attr.only_owner_release = false;
203    }
204
205    mutex_status = _CORE_mutex_Initialize(
206      &the_semaphore->Core_control.mutex,
207      _Thread_Get_executing(),
208      &the_mutex_attr,
209      count != 1
210    );
211
212    if ( mutex_status == CORE_MUTEX_STATUS_CEILING_VIOLATED ) {
213      _Semaphore_Free( the_semaphore );
214      _Objects_Allocator_unlock();
215      return RTEMS_INVALID_PRIORITY;
216    }
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.