source: rtems/cpukit/posix/src/semopen.c @ 21275b58

Last change on this file since 21275b58 was 21275b58, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 22, 2018 at 6:14:51 PM

score: Static Objects_Information initialization

Statically allocate the objects information together with the initial
set of objects either via <rtems/confdefs.h>. Provide default object
informations with zero objects via librtemscpu.a. This greatly
simplifies the workspace size estimate. RTEMS applications which do not
use the unlimited objects option are easier to debug since all objects
reside now in statically allocated objects of the right types.

Close #3621.

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Function Creates New POSIX semaphore or Opens an existing Semaphore
5 * @ingroup POSIXAPI
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2007.
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/posix/semaphoreimpl.h>
22#include <rtems/score/wkspace.h>
23#include <rtems/sysinit.h>
24
25#include <stdarg.h>
26#include <fcntl.h>
27#include <limits.h>
28
29static sem_t *_POSIX_Semaphore_Create_support(
30  const char   *name_arg,
31  size_t        name_len,
32  unsigned int  value
33)
34{
35  POSIX_Semaphore_Control *the_semaphore;
36  char                    *name;
37
38  if ( value > SEM_VALUE_MAX ) {
39    rtems_set_errno_and_return_value( EINVAL, SEM_FAILED );
40  }
41
42  /*
43   * Make a copy of the user's string for name just in case it was
44   * dynamically constructed.
45   */
46  name = _Workspace_String_duplicate( name_arg, name_len );
47  if ( name == NULL ) {
48    rtems_set_errno_and_return_value( ENOMEM, SEM_FAILED );
49  }
50
51  the_semaphore = _POSIX_Semaphore_Allocate_unprotected();
52  if ( the_semaphore == NULL ) {
53    _Workspace_Free( name );
54    rtems_set_errno_and_return_value( ENOSPC, SEM_FAILED );
55  }
56
57  the_semaphore->open_count = 1;
58  the_semaphore->linked = true;
59
60  /*
61   *  POSIX does not appear to specify what the discipline for
62   *  blocking tasks on this semaphore should be.  It could somehow
63   *  be derived from the current scheduling policy.  One
64   *  thing is certain, no matter what we decide, it won't be
65   *  the same as  all other POSIX implementations. :)
66   */
67  _POSIX_Semaphore_Initialize( &the_semaphore->Semaphore, name, value );
68
69  /*
70   *  Make the semaphore available for use.
71   */
72  _Objects_Open_string(
73    &_POSIX_Semaphore_Information,
74    &the_semaphore->Object,
75    name
76  );
77
78  return &the_semaphore->Semaphore;
79}
80
81/*
82 *  sem_open
83 *
84 *  Opens a named semaphore.  Used in conjunction with the sem_close
85 *  and sem_unlink commands.
86 *
87 *  11.2.3 Initialize/Open a Named Semaphore, P1003.1b-1993, p.221
88 *
89 *  NOTE: When oflag is O_CREAT, then optional third and fourth
90 *        parameters must be present.
91 */
92sem_t *sem_open(
93  const char *name,
94  int         oflag,
95  ...
96  /* mode_t mode, */
97  /* unsigned int value */
98)
99{
100  /*
101   * mode is set but never used. GCC gives a warning for this
102   * and we need to tell GCC not to complain. But we have to
103   * have it because we have to work through the variable
104   * arguments to get to attr.
105   */
106  mode_t                     mode RTEMS_UNUSED;
107
108  va_list                    arg;
109  unsigned int               value = 0;
110  POSIX_Semaphore_Control   *the_semaphore;
111  size_t                     name_len;
112  Objects_Get_by_name_error  error;
113  sem_t                     *sem;
114
115  if ( oflag & O_CREAT ) {
116    va_start(arg, oflag);
117    mode = va_arg( arg, mode_t );
118    value = va_arg( arg, unsigned int );
119    va_end(arg);
120  }
121
122  _Objects_Allocator_lock();
123  the_semaphore = _POSIX_Semaphore_Get_by_name( name, &name_len, &error );
124
125  /*
126   *  If the name to id translation worked, then the semaphore exists
127   *  and we can just return a pointer to the id.  Otherwise we may
128   *  need to check to see if this is a "semaphore does not exist"
129   *  or some other miscellaneous error on the name.
130   */
131
132  if ( the_semaphore == NULL ) {
133
134    /*
135     * Unless provided a valid name that did not already exist
136     * and we are willing to create then it is an error.
137     */
138
139    if ( !( error == OBJECTS_GET_BY_NAME_NO_OBJECT && (oflag & O_CREAT) ) ) {
140      _Objects_Allocator_unlock();
141      rtems_set_errno_and_return_value(
142        _POSIX_Get_by_name_error( error ),
143        SEM_FAILED
144      );
145    }
146  } else {
147
148    /*
149     * Check for existence with creation.
150     */
151
152    if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
153      _Objects_Allocator_unlock();
154      rtems_set_errno_and_return_value( EEXIST, SEM_FAILED );
155    }
156
157    the_semaphore->open_count += 1;
158    _Objects_Allocator_unlock();
159    return &the_semaphore->Semaphore;
160  }
161
162  /*
163   *  At this point, the semaphore does not exist and everything has been
164   *  checked. We should go ahead and create a semaphore.
165   */
166
167  sem = _POSIX_Semaphore_Create_support(
168    name,
169    name_len,
170    value
171  );
172
173  _Objects_Allocator_unlock();
174  return sem;
175}
176
177static void _POSIX_Semaphore_Manager_initialization( void )
178{
179  _Objects_Initialize_information( &_POSIX_Semaphore_Information );
180}
181
182RTEMS_SYSINIT_ITEM(
183  _POSIX_Semaphore_Manager_initialization,
184  RTEMS_SYSINIT_POSIX_SEMAPHORE,
185  RTEMS_SYSINIT_ORDER_MIDDLE
186);
Note: See TracBrowser for help on using the repository browser.