source: rtems/c/src/exec/posix/src/cond.c @ 37f4c2d

4.104.114.84.95
Last change on this file since 37f4c2d was 5e9b32b, checked in by Joel Sherrill <joel.sherrill@…>, on 09/26/95 at 19:27:15

posix support initially added

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