source: rtems/cpukit/posix/src/cond.c @ c238a218

4.104.114.84.95
Last change on this file since c238a218 was c238a218, checked in by Joel Sherrill <joel.sherrill@…>, on 05/31/96 at 21:40:48

added checks to validate values passed to set attribute routines

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