source: rtems/c/src/exec/posix/src/cond.c @ f4719d5a

4.104.114.84.95
Last change on this file since f4719d5a was f4719d5a, checked in by Joel Sherrill <joel.sherrill@…>, on 05/22/96 at 22:32:39

These files have been modified in the initial pass at getting the portion
of the POSIX API necessary to support the GNAT runtime to initially compile.
We now have verified that the specifications for the necessary routines
are correct per the POSIX standards we have.

  • Property mode set to 100644
File size: 8.7 KB
Line 
1/*  cond.c
2 *
3 *  $Id$
4 */
5
6#include <pthread.h>
7#include <errno.h>
8
9#include <rtems/system.h>
10#include <rtems/score/object.h>
11#include <rtems/score/states.h>
12#include <rtems/score/watchdog.h>
13#include <rtems/posix/cond.h>
14#include <rtems/posix/time.h>
15
16/*PAGE
17 *
18 *  The default condition variable attributes structure.
19 */
20 
21const pthread_condattr_t _POSIX_Condition_variables_Default_attributes = {
22  TRUE,                      /* is_initialized */
23  PTHREAD_PROCESS_PRIVATE    /* process_shared */
24};
25 
26/*PAGE
27 *
28 *  _POSIX_Condition_variables_Manager_initialization
29 *
30 *  This routine initializes all condition variable manager related data
31 *  structures.
32 *
33 *  Input parameters:
34 *    maximum_condition_variables - maximum configured condition_variables
35 *
36 *  Output parameters:  NONE
37 */
38 
39void _POSIX_Condition_variables_Manager_initialization(
40  unsigned32 maximum_condition_variables
41)
42{
43  _Objects_Initialize_information(
44    &_POSIX_Condition_variables_Information,
45    OBJECTS_POSIX_CONDITION_VARIABLES,
46    TRUE,
47    maximum_condition_variables,
48    sizeof( POSIX_Condition_variables_Control ),
49    FALSE,
50    0,
51    FALSE
52  );
53}
54
55/*PAGE
56 *
57 *  11.4.1 Condition Variable Initialization Attributes,
58 *            P1003.1c/Draft 10, p. 96
59 */
60 
61int pthread_condattr_init(
62  pthread_condattr_t *attr
63)
64{
65  if ( !attr )
66    return EINVAL;
67
68  *attr = _POSIX_Condition_variables_Default_attributes;
69  return 0;
70}
71 
72/*PAGE
73 *
74 *  11.4.1 Condition Variable Initialization Attributes,
75 *            P1003.1c/Draft 10, p. 96
76 */
77 
78int pthread_condattr_destroy(
79  pthread_condattr_t *attr
80)
81{
82  if ( !attr || attr->is_initialized == FALSE )
83    return EINVAL;
84
85  attr->is_initialized = FALSE;
86  return 0;
87}
88 
89/*PAGE
90 *
91 *  11.4.1 Condition Variable Initialization Attributes,
92 *            P1003.1c/Draft 10, p. 96
93 */
94 
95int pthread_condattr_getpshared(
96  const pthread_condattr_t *attr,
97  int                      *pshared
98)
99{
100  if ( !attr )
101    return EINVAL;
102
103  *pshared = attr->process_shared;
104  return 0;
105}
106 
107/*PAGE
108 *
109 *  11.4.1 Condition Variable Initialization Attributes,
110 *            P1003.1c/Draft 10, p. 96
111 */
112 
113int pthread_condattr_setpshared(
114  pthread_condattr_t *attr,
115  int                 pshared
116)
117{
118  if ( !attr )
119    return EINVAL;
120
121  attr->process_shared = pshared;
122  return 0;
123}
124 
125/*PAGE
126 *
127 *  11.4.2 Initializing and Destroying a Condition Variable,
128 *         P1003.1c/Draft 10, p. 87
129 */
130 
131int pthread_cond_init(
132  pthread_cond_t           *cond,
133  const pthread_condattr_t *attr
134)
135{
136  POSIX_Condition_variables_Control   *the_cond;
137  const pthread_condattr_t            *the_attr;
138 
139  if ( attr ) the_attr = attr;
140  else        the_attr = &_POSIX_Condition_variables_Default_attributes;
141 
142  /*
143   *  XXX: Be careful about attributes when global!!!
144   */
145 
146  if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
147    return POSIX_MP_NOT_IMPLEMENTED();
148 
149  if ( !the_attr->is_initialized )
150    return EINVAL;
151 
152  _Thread_Disable_dispatch();
153 
154  the_cond = _POSIX_Condition_variables_Allocate();
155 
156  if ( !the_cond ) {
157    _Thread_Enable_dispatch();
158    return ENOMEM;
159  }
160 
161  if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&
162     !( _Objects_MP_Allocate_and_open( &_POSIX_Condition_variables_Information,
163                0, the_cond->Object.id, FALSE ) ) ) {
164    _POSIX_Condition_variables_Free( the_cond );
165    _Thread_Enable_dispatch();
166    return EAGAIN;
167  }
168 
169  the_cond->process_shared  = the_attr->process_shared;
170
171  the_cond->Mutex = 0;
172
173/* XXX some more initialization might need to go here */
174  _Thread_queue_Initialize(
175    &the_cond->Wait_queue,
176    OBJECTS_POSIX_CONDITION_VARIABLES,
177    THREAD_QUEUE_DISCIPLINE_FIFO,
178    STATES_WAITING_FOR_CONDITION_VARIABLE,
179    _POSIX_Condition_variables_MP_Send_extract_proxy,
180    ETIMEDOUT
181  );
182
183  _Objects_Open(
184    &_POSIX_Condition_variables_Information,
185    &the_cond->Object,
186    0
187  );
188 
189  *cond = the_cond->Object.id;
190 
191  if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
192    _POSIX_Condition_variables_MP_Send_process_packet(
193      POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_CREATE,
194      the_cond->Object.id,
195      0,                         /* Name not used */
196      0                          /* Not used */
197    );
198 
199  _Thread_Enable_dispatch();
200
201  return 0;
202}
203 
204/*PAGE
205 *
206 *  11.4.2 Initializing and Destroying a Condition Variable,
207 *         P1003.1c/Draft 10, p. 87
208 */
209 
210int pthread_cond_destroy(
211  pthread_cond_t           *cond
212)
213{
214  register POSIX_Condition_variables_Control *the_cond;
215  Objects_Locations                           location;
216 
217  the_cond = _POSIX_Condition_variables_Get( cond, &location );
218  switch ( location ) {
219    case OBJECTS_ERROR:
220      return EINVAL;
221    case OBJECTS_REMOTE:
222      _Thread_Dispatch();
223      return POSIX_MP_NOT_IMPLEMENTED();
224      return EINVAL;
225    case OBJECTS_LOCAL:
226 
227      _Objects_Close(
228        &_POSIX_Condition_variables_Information,
229        &the_cond->Object
230      );
231 
232      if ( _Thread_queue_Get_number_waiting( &the_cond->Wait_queue ) )
233        return EBUSY;
234 
235      _POSIX_Condition_variables_Free( the_cond );
236 
237      if ( the_cond->process_shared == PTHREAD_PROCESS_SHARED ) {
238 
239        _Objects_MP_Close(
240          &_POSIX_Condition_variables_Information,
241          the_cond->Object.id
242        );
243 
244        _POSIX_Condition_variables_MP_Send_process_packet(
245          POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_DELETE,
246          the_cond->Object.id,
247          0,                         /* Not used */
248          0                          /* Not used */
249        );
250      }
251      _Thread_Enable_dispatch();
252      return 0;
253  }
254  return POSIX_BOTTOM_REACHED();
255}
256 
257/*PAGE
258 *
259 *  _POSIX_Condition_variables_Signal_support
260 *
261 *  A support routine which implements guts of the broadcast and single task
262 *  wake up version of the "signal" operation.
263 */
264 
265int _POSIX_Condition_variables_Signal_support(
266  pthread_cond_t            *cond,
267  boolean                    is_broadcast
268)
269{
270  register POSIX_Condition_variables_Control *the_cond;
271  Objects_Locations                           location;
272  Thread_Control                             *the_thread;
273 
274  the_cond = _POSIX_Condition_variables_Get( cond, &location );
275  switch ( location ) {
276    case OBJECTS_ERROR:
277      return EINVAL;
278    case OBJECTS_REMOTE:
279      _Thread_Dispatch();
280      return POSIX_MP_NOT_IMPLEMENTED();
281      return EINVAL;
282    case OBJECTS_LOCAL:
283 
284      do {
285        the_thread = _Thread_queue_Dequeue( &the_cond->Wait_queue );
286      } while ( is_broadcast && the_thread );
287      return 0;
288  }
289  return POSIX_BOTTOM_REACHED();
290}
291
292/*PAGE
293 *
294 *  11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
295 */
296 
297int pthread_cond_signal(
298  pthread_cond_t   *cond
299)
300{
301  return _POSIX_Condition_variables_Signal_support( cond, FALSE );
302}
303 
304/*PAGE
305 *
306 *  11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
307 */
308 
309int pthread_cond_broadcast(
310  pthread_cond_t   *cond
311)
312{
313  return _POSIX_Condition_variables_Signal_support( cond, TRUE );
314}
315 
316/*PAGE
317 *
318 *  _POSIX_Condition_variables_Wait_support
319 *
320 *  A support routine which implements guts of the blocking, non-blocking, and
321 *  timed wait version of condition variable wait routines.
322 */
323 
324int _POSIX_Condition_variables_Wait_support(
325  pthread_cond_t            *cond,
326  pthread_mutex_t           *mutex,
327  Watchdog_Interval          timeout
328)
329{
330  register POSIX_Condition_variables_Control *the_cond;
331  Objects_Locations                           location;
332  int                                         status;
333 
334  the_cond = _POSIX_Condition_variables_Get( cond, &location );
335  switch ( location ) {
336    case OBJECTS_ERROR:
337      return EINVAL;
338    case OBJECTS_REMOTE:
339      _Thread_Dispatch();
340      return POSIX_MP_NOT_IMPLEMENTED();
341      return EINVAL;
342    case OBJECTS_LOCAL:
343 
344      /*
345       *  XXX: should be an error if cond->Mutex != mutex
346       */
347 
348      status = pthread_mutex_unlock( mutex );
349      if ( !status )
350        return status;
351 
352      the_cond->Mutex = *mutex;
353 
354/* XXX .. enter critical section .. */
355      _Thread_queue_Enqueue( &the_cond->Wait_queue, 0 );
356
357      _Thread_Enable_dispatch();
358
359      status = pthread_mutex_lock( mutex );
360      if ( !status )
361        return status;
362   
363      return _Thread_Executing->Wait.return_code;
364  }
365  return POSIX_BOTTOM_REACHED();
366}
367
368/*PAGE
369 *
370 *  11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
371 */
372 
373int pthread_cond_wait(
374  pthread_cond_t     *cond,
375  pthread_mutex_t    *mutex
376)
377{
378  return _POSIX_Condition_variables_Wait_support(
379    cond,
380    mutex,
381    THREAD_QUEUE_WAIT_FOREVER
382  );
383}
384 
385/*PAGE
386 *
387 *  11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
388 */
389 
390int pthread_cond_timedwait(
391  pthread_cond_t        *cond,
392  pthread_mutex_t       *mutex,
393  const struct timespec *abstime
394)
395{
396  return _POSIX_Condition_variables_Wait_support(
397    cond,
398    mutex,
399    _POSIX_Time_Spec_to_interval( abstime )
400  );
401}
Note: See TracBrowser for help on using the repository browser.