source: rtems/c/src/exec/posix/src/cond.c @ 7f72217e

4.104.114.84.95
Last change on this file since 7f72217e was 7f72217e, checked in by Joel Sherrill <joel.sherrill@…>, on 05/29/96 at 21:27:26

comment clean up

  • Property mode set to 100644
File size: 9.2 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  attr->process_shared = pshared;
146  return 0;
147}
148 
149/*PAGE
150 *
151 *  11.4.2 Initializing and Destroying a Condition Variable,
152 *         P1003.1c/Draft 10, p. 87
153 */
154 
155int pthread_cond_init(
156  pthread_cond_t           *cond,
157  const pthread_condattr_t *attr
158)
159{
160  POSIX_Condition_variables_Control   *the_cond;
161  const pthread_condattr_t            *the_attr;
162 
163  if ( attr ) the_attr = attr;
164  else        the_attr = &_POSIX_Condition_variables_Default_attributes;
165 
166  /*
167   *  XXX: Be careful about attributes when global!!!
168   */
169 
170  if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
171    return POSIX_MP_NOT_IMPLEMENTED();
172 
173  if ( !the_attr->is_initialized )
174    return EINVAL;
175 
176  _Thread_Disable_dispatch();
177 
178  the_cond = _POSIX_Condition_variables_Allocate();
179 
180  if ( !the_cond ) {
181    _Thread_Enable_dispatch();
182    return ENOMEM;
183  }
184 
185  if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&
186     !( _Objects_MP_Allocate_and_open( &_POSIX_Condition_variables_Information,
187                0, the_cond->Object.id, FALSE ) ) ) {
188    _POSIX_Condition_variables_Free( the_cond );
189    _Thread_Enable_dispatch();
190    return EAGAIN;
191  }
192 
193  the_cond->process_shared  = the_attr->process_shared;
194
195  the_cond->Mutex = 0;
196
197/* XXX some more initialization might need to go here */
198  _Thread_queue_Initialize(
199    &the_cond->Wait_queue,
200    OBJECTS_POSIX_CONDITION_VARIABLES,
201    THREAD_QUEUE_DISCIPLINE_FIFO,
202    STATES_WAITING_FOR_CONDITION_VARIABLE,
203    _POSIX_Condition_variables_MP_Send_extract_proxy,
204    ETIMEDOUT
205  );
206
207  _Objects_Open(
208    &_POSIX_Condition_variables_Information,
209    &the_cond->Object,
210    0
211  );
212 
213  *cond = the_cond->Object.id;
214 
215  if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
216    _POSIX_Condition_variables_MP_Send_process_packet(
217      POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_CREATE,
218      the_cond->Object.id,
219      0,                         /* Name not used */
220      0                          /* Not used */
221    );
222 
223  _Thread_Enable_dispatch();
224
225  return 0;
226}
227 
228/*PAGE
229 *
230 *  11.4.2 Initializing and Destroying a Condition Variable,
231 *         P1003.1c/Draft 10, p. 87
232 */
233 
234int pthread_cond_destroy(
235  pthread_cond_t           *cond
236)
237{
238  register POSIX_Condition_variables_Control *the_cond;
239  Objects_Locations                           location;
240 
241  the_cond = _POSIX_Condition_variables_Get( cond, &location );
242  switch ( location ) {
243    case OBJECTS_ERROR:
244      return EINVAL;
245    case OBJECTS_REMOTE:
246      _Thread_Dispatch();
247      return POSIX_MP_NOT_IMPLEMENTED();
248      return EINVAL;
249    case OBJECTS_LOCAL:
250 
251      _Objects_Close(
252        &_POSIX_Condition_variables_Information,
253        &the_cond->Object
254      );
255 
256      if ( _Thread_queue_Get_number_waiting( &the_cond->Wait_queue ) )
257        return EBUSY;
258 
259      _POSIX_Condition_variables_Free( the_cond );
260 
261      if ( the_cond->process_shared == PTHREAD_PROCESS_SHARED ) {
262 
263        _Objects_MP_Close(
264          &_POSIX_Condition_variables_Information,
265          the_cond->Object.id
266        );
267 
268        _POSIX_Condition_variables_MP_Send_process_packet(
269          POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_DELETE,
270          the_cond->Object.id,
271          0,                         /* Not used */
272          0                          /* Not used */
273        );
274      }
275      _Thread_Enable_dispatch();
276      return 0;
277  }
278  return POSIX_BOTTOM_REACHED();
279}
280 
281/*PAGE
282 *
283 *  _POSIX_Condition_variables_Signal_support
284 *
285 *  A support routine which implements guts of the broadcast and single task
286 *  wake up version of the "signal" operation.
287 */
288 
289int _POSIX_Condition_variables_Signal_support(
290  pthread_cond_t            *cond,
291  boolean                    is_broadcast
292)
293{
294  register POSIX_Condition_variables_Control *the_cond;
295  Objects_Locations                           location;
296  Thread_Control                             *the_thread;
297 
298  the_cond = _POSIX_Condition_variables_Get( cond, &location );
299  switch ( location ) {
300    case OBJECTS_ERROR:
301      return EINVAL;
302    case OBJECTS_REMOTE:
303      _Thread_Dispatch();
304      return POSIX_MP_NOT_IMPLEMENTED();
305      return EINVAL;
306    case OBJECTS_LOCAL:
307 
308      do {
309        the_thread = _Thread_queue_Dequeue( &the_cond->Wait_queue );
310      } while ( is_broadcast && the_thread );
311      return 0;
312  }
313  return POSIX_BOTTOM_REACHED();
314}
315
316/*PAGE
317 *
318 *  11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
319 */
320 
321int pthread_cond_signal(
322  pthread_cond_t   *cond
323)
324{
325  return _POSIX_Condition_variables_Signal_support( cond, FALSE );
326}
327 
328/*PAGE
329 *
330 *  11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
331 */
332 
333int pthread_cond_broadcast(
334  pthread_cond_t   *cond
335)
336{
337  return _POSIX_Condition_variables_Signal_support( cond, TRUE );
338}
339 
340/*PAGE
341 *
342 *  _POSIX_Condition_variables_Wait_support
343 *
344 *  A support routine which implements guts of the blocking, non-blocking, and
345 *  timed wait version of condition variable wait routines.
346 */
347 
348int _POSIX_Condition_variables_Wait_support(
349  pthread_cond_t            *cond,
350  pthread_mutex_t           *mutex,
351  Watchdog_Interval          timeout
352)
353{
354  register POSIX_Condition_variables_Control *the_cond;
355  Objects_Locations                           location;
356  int                                         status;
357 
358  the_cond = _POSIX_Condition_variables_Get( cond, &location );
359  switch ( location ) {
360    case OBJECTS_ERROR:
361      return EINVAL;
362    case OBJECTS_REMOTE:
363      _Thread_Dispatch();
364      return POSIX_MP_NOT_IMPLEMENTED();
365      return EINVAL;
366    case OBJECTS_LOCAL:
367 
368      /*
369       *  XXX: should be an error if cond->Mutex != mutex
370       */
371 
372      status = pthread_mutex_unlock( mutex );
373      if ( !status )
374        return status;
375 
376      the_cond->Mutex = *mutex;
377 
378/* XXX .. enter critical section .. */
379      _Thread_queue_Enqueue( &the_cond->Wait_queue, 0 );
380
381      _Thread_Enable_dispatch();
382
383      status = pthread_mutex_lock( mutex );
384      if ( !status )
385        return status;
386   
387      return _Thread_Executing->Wait.return_code;
388  }
389  return POSIX_BOTTOM_REACHED();
390}
391
392/*PAGE
393 *
394 *  11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
395 */
396 
397int pthread_cond_wait(
398  pthread_cond_t     *cond,
399  pthread_mutex_t    *mutex
400)
401{
402  return _POSIX_Condition_variables_Wait_support(
403    cond,
404    mutex,
405    THREAD_QUEUE_WAIT_FOREVER
406  );
407}
408 
409/*PAGE
410 *
411 *  11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
412 */
413 
414int pthread_cond_timedwait(
415  pthread_cond_t        *cond,
416  pthread_mutex_t       *mutex,
417  const struct timespec *abstime
418)
419{
420  return _POSIX_Condition_variables_Wait_support(
421    cond,
422    mutex,
423    _POSIX_Time_Spec_to_interval( abstime )
424  );
425}
Note: See TracBrowser for help on using the repository browser.