source: rtems/cpukit/posix/src/cond.c @ 8bdcfc4

4.104.114.84.95
Last change on this file since 8bdcfc4 was 67d224a, checked in by Joel Sherrill <joel.sherrill@…>, on 12/08/95 at 21:06:15

added correct use of _Thread_queue_Enter_critical_section

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