Changeset 98dca75 in rtems


Ignore:
Timestamp:
Nov 2, 1999, 6:25:26 PM (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
9f95a19
Parents:
799c767
Message:

Split condition variables into multiple files.

Files:
24 added
5 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/posix/include/rtems/posix/cond.h

    r799c767 r98dca75  
    4949 
    5050POSIX_EXTERN Objects_Information  _POSIX_Condition_variables_Information;
     51
     52/*
     53 *  The default condition variable attributes structure.
     54 */
     55
     56extern const pthread_condattr_t _POSIX_Condition_variables_Default_attributes;
    5157 
    5258/*
     
    119125);
    120126
     127/*
     128 *  _POSIX_Condition_variables_Signal_support
     129 *
     130 *  DESCRIPTION:
     131 *
     132 *  A support routine which implements guts of the broadcast and single task
     133 *  wake up version of the "signal" operation.
     134 */
     135
     136int _POSIX_Condition_variables_Signal_support(
     137  pthread_cond_t            *cond,
     138  boolean                    is_broadcast
     139);
     140
     141/*
     142 *  _POSIX_Condition_variables_Wait_support
     143 *
     144 *  DESCRIPTION:
     145 *
     146 *  A support routine which implements guts of the blocking, non-blocking, and
     147 *  timed wait version of condition variable wait routines.
     148 */
     149
     150int _POSIX_Condition_variables_Wait_support(
     151  pthread_cond_t            *cond,
     152  pthread_mutex_t           *mutex,
     153  Watchdog_Interval          timeout,
     154  boolean                    already_timedout
     155);
     156
    121157#include <rtems/posix/cond.inl>
    122158#if defined(RTEMS_MULTIPROCESSING)
  • c/src/exec/posix/src/Makefile.in

    r799c767 r98dca75  
    2323    wait waitpid
    2424
    25 MESSAGE_QUEUE_PIECES= mqueue mqueueclose mqueuecreatesupp mqueuedeletesupp \
     25CONDITION_VARIABLE_C_PIECES= cond condattrdestroy condattrgetpshared \
     26    condattrinit condattrsetpshared condbroadcast conddefaultattributes \
     27    condmp condsignal condsignalsupp condtimedwait condwait condwaitsupp
     28
     29MESSAGE_QUEUE_C_PIECES= mqueue mqueueclose mqueuecreatesupp mqueuedeletesupp \
    2630    mqueuegetattr mqueuenametoid mqueuenotify mqueueopen mqueuereceive \
    2731    mqueuerecvsupp mqueuesend mqueuesendsupp mqueuesetattr \
     
    5963    semunlink semwait
    6064
    61 C_PIECES = adasupp cond getpid key $(MESSAGE_QUEUE_PIECES) \
     65C_PIECES = adasupp $(CONDITION_VARIABLE_C_PIECES) \
     66    getpid key $(MESSAGE_QUEUE_C_PIECES) \
    6267    $(MUTEX_C_PIECES) $(PTHREAD_C_PIECES) \
    6368    $(PSIGNAL_C_PIECES) ptimer sched $(SEMAPHORE_C_PIECES) \
  • c/src/exec/posix/src/cond.c

    r799c767 r98dca75  
    1414#include <rtems/posix/mutex.h>
    1515
    16 /*
    17  *  TEMPORARY
    18  */
    19 
    20 
    21 #if defined(RTEMS_MULTIPROCESSING)
    22 void _POSIX_Condition_variables_MP_Send_process_packet (
    23   POSIX_Condition_variables_MP_Remote_operations  operation,
    24   Objects_Id                        condition_variables_id,
    25   Objects_Name                      name,
    26   Objects_Id                        proxy_id
    27 )
    28 {
    29   (void) POSIX_MP_NOT_IMPLEMENTED();
    30 }
    31 
    32 void _POSIX_Condition_variables_MP_Send_extract_proxy(
    33   Thread_Control *the_thread
    34 )
    35 {
    36   (void) POSIX_MP_NOT_IMPLEMENTED();
    37 }
    38 #endif
    39 
    40 /*
    41  *  END OF TEMPORARY
    42  */
    43 
    44 /*PAGE
    45  *
    46  *  The default condition variable attributes structure.
    47  */
    48  
    49 const pthread_condattr_t _POSIX_Condition_variables_Default_attributes = {
    50   TRUE,                      /* is_initialized */
    51   PTHREAD_PROCESS_PRIVATE    /* process_shared */
    52 };
    53  
    5416/*PAGE
    5517 *
     
    8042  );
    8143}
    82 
    83 /*PAGE
    84  *
    85  *  11.4.1 Condition Variable Initialization Attributes,
    86  *            P1003.1c/Draft 10, p. 96
    87  */
    88  
    89 int pthread_condattr_init(
    90   pthread_condattr_t *attr
    91 )
    92 {
    93   if ( !attr )
    94     return EINVAL;
    95 
    96   *attr = _POSIX_Condition_variables_Default_attributes;
    97   return 0;
    98 }
    99  
    100 /*PAGE
    101  *
    102  *  11.4.1 Condition Variable Initialization Attributes,
    103  *            P1003.1c/Draft 10, p. 96
    104  */
    105  
    106 int pthread_condattr_destroy(
    107   pthread_condattr_t *attr
    108 )
    109 {
    110   if ( !attr || attr->is_initialized == FALSE )
    111     return EINVAL;
    112 
    113   attr->is_initialized = FALSE;
    114   return 0;
    115 }
    116  
    117 /*PAGE
    118  *
    119  *  11.4.1 Condition Variable Initialization Attributes,
    120  *            P1003.1c/Draft 10, p. 96
    121  */
    122  
    123 int pthread_condattr_getpshared(
    124   const pthread_condattr_t *attr,
    125   int                      *pshared
    126 )
    127 {
    128   if ( !attr )
    129     return EINVAL;
    130 
    131   *pshared = attr->process_shared;
    132   return 0;
    133 }
    134  
    135 /*PAGE
    136  *
    137  *  11.4.1 Condition Variable Initialization Attributes,
    138  *            P1003.1c/Draft 10, p. 96
    139  */
    140  
    141 int pthread_condattr_setpshared(
    142   pthread_condattr_t *attr,
    143   int                 pshared
    144 )
    145 {
    146   if ( !attr )
    147     return EINVAL;
    148 
    149   switch ( pshared ) {
    150     case PTHREAD_PROCESS_SHARED:
    151     case PTHREAD_PROCESS_PRIVATE:
    152       attr->process_shared = pshared;
    153       return 0;
    154 
    155     default:
    156       return EINVAL;
    157   }
    158 }
    159  
    160 /*PAGE
    161  *
    162  *  11.4.2 Initializing and Destroying a Condition Variable,
    163  *         P1003.1c/Draft 10, p. 87
    164  */
    165  
    166 int pthread_cond_init(
    167   pthread_cond_t           *cond,
    168   const pthread_condattr_t *attr
    169 )
    170 {
    171   POSIX_Condition_variables_Control   *the_cond;
    172   const pthread_condattr_t            *the_attr;
    173  
    174   if ( attr ) the_attr = attr;
    175   else        the_attr = &_POSIX_Condition_variables_Default_attributes;
    176  
    177   /*
    178    *  XXX: Be careful about attributes when global!!!
    179    */
    180  
    181   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
    182     return POSIX_MP_NOT_IMPLEMENTED();
    183  
    184   if ( !the_attr->is_initialized )
    185     return EINVAL;
    186  
    187   _Thread_Disable_dispatch();
    188  
    189   the_cond = _POSIX_Condition_variables_Allocate();
    190  
    191   if ( !the_cond ) {
    192     _Thread_Enable_dispatch();
    193     return ENOMEM;
    194   }
    195  
    196 #if defined(RTEMS_MULTIPROCESSING)
    197   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&
    198      !( _Objects_MP_Allocate_and_open( &_POSIX_Condition_variables_Information,
    199                 0, the_cond->Object.id, FALSE ) ) ) {
    200     _POSIX_Condition_variables_Free( the_cond );
    201     _Thread_Enable_dispatch();
    202     return EAGAIN;
    203   }
    204 #endif
    205  
    206   the_cond->process_shared  = the_attr->process_shared;
    207 
    208   the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
    209 
    210 /* XXX some more initialization might need to go here */
    211   _Thread_queue_Initialize(
    212     &the_cond->Wait_queue,
    213     OBJECTS_POSIX_CONDITION_VARIABLES,
    214     THREAD_QUEUE_DISCIPLINE_FIFO,
    215     STATES_WAITING_FOR_CONDITION_VARIABLE,
    216 #if defined(RTEMS_MULTIPROCESSING)
    217     _POSIX_Condition_variables_MP_Send_extract_proxy,
    218 #else
    219     NULL,
    220 #endif
    221     ETIMEDOUT
    222   );
    223 
    224   _Objects_Open(
    225     &_POSIX_Condition_variables_Information,
    226     &the_cond->Object,
    227     0
    228   );
    229  
    230   *cond = the_cond->Object.id;
    231  
    232 #if defined(RTEMS_MULTIPROCESSING)
    233   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
    234     _POSIX_Condition_variables_MP_Send_process_packet(
    235       POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_CREATE,
    236       the_cond->Object.id,
    237       0,                         /* Name not used */
    238       0                          /* Not used */
    239     );
    240 #endif
    241  
    242   _Thread_Enable_dispatch();
    243 
    244   return 0;
    245 }
    246  
    247 /*PAGE
    248  *
    249  *  11.4.2 Initializing and Destroying a Condition Variable,
    250  *         P1003.1c/Draft 10, p. 87
    251  */
    252  
    253 int pthread_cond_destroy(
    254   pthread_cond_t           *cond
    255 )
    256 {
    257   register POSIX_Condition_variables_Control *the_cond;
    258   Objects_Locations                           location;
    259  
    260   the_cond = _POSIX_Condition_variables_Get( cond, &location );
    261   switch ( location ) {
    262     case OBJECTS_REMOTE:
    263 #if defined(RTEMS_MULTIPROCESSING)
    264       _Thread_Dispatch();
    265       return POSIX_MP_NOT_IMPLEMENTED();
    266       return EINVAL;
    267 #endif
    268 
    269     case OBJECTS_ERROR:
    270       return EINVAL;
    271 
    272 
    273     case OBJECTS_LOCAL:
    274  
    275       if ( _Thread_queue_First( &the_cond->Wait_queue ) ) {
    276         _Thread_Enable_dispatch();
    277         return EBUSY;
    278       }
    279  
    280       _Objects_Close(
    281         &_POSIX_Condition_variables_Information,
    282         &the_cond->Object
    283       );
    284  
    285       _POSIX_Condition_variables_Free( the_cond );
    286  
    287 #if defined(RTEMS_MULTIPROCESSING)
    288       if ( the_cond->process_shared == PTHREAD_PROCESS_SHARED ) {
    289  
    290         _Objects_MP_Close(
    291           &_POSIX_Condition_variables_Information,
    292           the_cond->Object.id
    293         );
    294  
    295         _POSIX_Condition_variables_MP_Send_process_packet(
    296           POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_DELETE,
    297           the_cond->Object.id,
    298           0,                         /* Not used */
    299           0                          /* Not used */
    300         );
    301       }
    302 #endif
    303       _Thread_Enable_dispatch();
    304       return 0;
    305   }
    306   return POSIX_BOTTOM_REACHED();
    307 }
    308  
    309 /*PAGE
    310  *
    311  *  _POSIX_Condition_variables_Signal_support
    312  *
    313  *  A support routine which implements guts of the broadcast and single task
    314  *  wake up version of the "signal" operation.
    315  */
    316  
    317 int _POSIX_Condition_variables_Signal_support(
    318   pthread_cond_t            *cond,
    319   boolean                    is_broadcast
    320 )
    321 {
    322   register POSIX_Condition_variables_Control *the_cond;
    323   Objects_Locations                           location;
    324   Thread_Control                             *the_thread;
    325  
    326   the_cond = _POSIX_Condition_variables_Get( cond, &location );
    327   switch ( location ) {
    328     case OBJECTS_REMOTE:
    329 #if defined(RTEMS_MULTIPROCESSING)
    330       _Thread_Dispatch();
    331       return POSIX_MP_NOT_IMPLEMENTED();
    332       return EINVAL;
    333 #endif
    334 
    335     case OBJECTS_ERROR:
    336       return EINVAL;
    337     case OBJECTS_LOCAL:
    338  
    339       do {
    340         the_thread = _Thread_queue_Dequeue( &the_cond->Wait_queue );
    341         if ( !the_thread )
    342           the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
    343       } while ( is_broadcast && the_thread );
    344 
    345       _Thread_Enable_dispatch();
    346 
    347       return 0;
    348   }
    349   return POSIX_BOTTOM_REACHED();
    350 }
    351 
    352 /*PAGE
    353  *
    354  *  11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
    355  */
    356  
    357 int pthread_cond_signal(
    358   pthread_cond_t   *cond
    359 )
    360 {
    361   return _POSIX_Condition_variables_Signal_support( cond, FALSE );
    362 }
    363  
    364 /*PAGE
    365  *
    366  *  11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
    367  */
    368  
    369 int pthread_cond_broadcast(
    370   pthread_cond_t   *cond
    371 )
    372 {
    373   return _POSIX_Condition_variables_Signal_support( cond, TRUE );
    374 }
    375  
    376 /*PAGE
    377  *
    378  *  _POSIX_Condition_variables_Wait_support
    379  *
    380  *  A support routine which implements guts of the blocking, non-blocking, and
    381  *  timed wait version of condition variable wait routines.
    382  */
    383  
    384 int _POSIX_Condition_variables_Wait_support(
    385   pthread_cond_t            *cond,
    386   pthread_mutex_t           *mutex,
    387   Watchdog_Interval          timeout,
    388   boolean                    already_timedout
    389 )
    390 {
    391   register POSIX_Condition_variables_Control *the_cond;
    392   Objects_Locations                           location;
    393   int                                         status;
    394   int                                         mutex_status;
    395  
    396   if ( !_POSIX_Mutex_Get( mutex, &location ) ) {
    397      return EINVAL;
    398   }
    399 
    400   _Thread_Unnest_dispatch();
    401 
    402   the_cond = _POSIX_Condition_variables_Get( cond, &location );
    403   switch ( location ) {
    404     case OBJECTS_REMOTE:
    405 #if defined(RTEMS_MULTIPROCESSING)
    406       _Thread_Dispatch();
    407       return POSIX_MP_NOT_IMPLEMENTED();
    408       return EINVAL;
    409 #endif
    410     case OBJECTS_ERROR:
    411       return EINVAL;
    412     case OBJECTS_LOCAL:
    413  
    414       if ( the_cond->Mutex && ( the_cond->Mutex != *mutex ) ) {
    415         _Thread_Enable_dispatch();
    416         return EINVAL;
    417       }
    418  
    419       (void) pthread_mutex_unlock( mutex );
    420 /* XXX ignore this for now  since behavior is undefined
    421       if ( mutex_status ) {
    422         _Thread_Enable_dispatch();
    423         return EINVAL;
    424       }
    425 */
    426 
    427       if ( !already_timedout ) {
    428         the_cond->Mutex = *mutex;
    429  
    430         _Thread_queue_Enter_critical_section( &the_cond->Wait_queue );
    431         _Thread_Executing->Wait.return_code = 0;
    432         _Thread_Executing->Wait.queue       = &the_cond->Wait_queue;
    433         _Thread_Executing->Wait.id          = *cond;
    434 
    435         _Thread_queue_Enqueue( &the_cond->Wait_queue, timeout );
    436 
    437         _Thread_Enable_dispatch();
    438 
    439         /*
    440          *  Switch ourself out because we blocked as a result of the
    441          *  _Thread_queue_Enqueue.
    442          */
    443 
    444         status = _Thread_Executing->Wait.return_code;
    445         if ( status && status != ETIMEDOUT )
    446           return status;
    447 
    448       } else {
    449         _Thread_Enable_dispatch();
    450         status = ETIMEDOUT;
    451       }
    452 
    453       /*
    454        *  When we get here the dispatch disable level is 0.
    455        */
    456 
    457       mutex_status = pthread_mutex_lock( mutex );
    458       if ( mutex_status )
    459         return EINVAL;
    460    
    461       return status;
    462   }
    463   return POSIX_BOTTOM_REACHED();
    464 }
    465 
    466 /*PAGE
    467  *
    468  *  11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
    469  */
    470  
    471 int pthread_cond_wait(
    472   pthread_cond_t     *cond,
    473   pthread_mutex_t    *mutex
    474 )
    475 {
    476   return _POSIX_Condition_variables_Wait_support(
    477     cond,
    478     mutex,
    479     THREAD_QUEUE_WAIT_FOREVER,
    480     FALSE
    481   );
    482 }
    483  
    484 /*PAGE
    485  *
    486  *  11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
    487  */
    488  
    489 int pthread_cond_timedwait(
    490   pthread_cond_t        *cond,
    491   pthread_mutex_t       *mutex,
    492   const struct timespec *abstime
    493 )
    494 {
    495   Watchdog_Interval timeout;
    496   struct timespec   current_time;
    497   struct timespec   difference;
    498   boolean           already_timedout = FALSE;
    499 
    500   if ( !abstime )
    501     return EINVAL;
    502 
    503   /*
    504    *  The abstime is a walltime.  We turn it into an interval.
    505    */
    506 
    507   (void) clock_gettime( CLOCK_REALTIME, &current_time );
    508 
    509   /* XXX probably some error checking should go here */
    510 
    511   _POSIX_Timespec_subtract( &current_time, abstime, &difference );
    512 
    513   if ( ( difference.tv_sec < 0 ) || ( ( difference.tv_sec == 0 ) &&
    514        ( difference.tv_nsec < 0 ) ) )
    515     already_timedout = TRUE;   
    516 
    517   timeout = _POSIX_Timespec_to_interval( &difference );
    518 
    519   return _POSIX_Condition_variables_Wait_support(
    520     cond,
    521     mutex,
    522     timeout,
    523     already_timedout
    524   );
    525 }
  • cpukit/posix/include/rtems/posix/cond.h

    r799c767 r98dca75  
    4949 
    5050POSIX_EXTERN Objects_Information  _POSIX_Condition_variables_Information;
     51
     52/*
     53 *  The default condition variable attributes structure.
     54 */
     55
     56extern const pthread_condattr_t _POSIX_Condition_variables_Default_attributes;
    5157 
    5258/*
     
    119125);
    120126
     127/*
     128 *  _POSIX_Condition_variables_Signal_support
     129 *
     130 *  DESCRIPTION:
     131 *
     132 *  A support routine which implements guts of the broadcast and single task
     133 *  wake up version of the "signal" operation.
     134 */
     135
     136int _POSIX_Condition_variables_Signal_support(
     137  pthread_cond_t            *cond,
     138  boolean                    is_broadcast
     139);
     140
     141/*
     142 *  _POSIX_Condition_variables_Wait_support
     143 *
     144 *  DESCRIPTION:
     145 *
     146 *  A support routine which implements guts of the blocking, non-blocking, and
     147 *  timed wait version of condition variable wait routines.
     148 */
     149
     150int _POSIX_Condition_variables_Wait_support(
     151  pthread_cond_t            *cond,
     152  pthread_mutex_t           *mutex,
     153  Watchdog_Interval          timeout,
     154  boolean                    already_timedout
     155);
     156
    121157#include <rtems/posix/cond.inl>
    122158#if defined(RTEMS_MULTIPROCESSING)
  • cpukit/posix/src/cond.c

    r799c767 r98dca75  
    1414#include <rtems/posix/mutex.h>
    1515
    16 /*
    17  *  TEMPORARY
    18  */
    19 
    20 
    21 #if defined(RTEMS_MULTIPROCESSING)
    22 void _POSIX_Condition_variables_MP_Send_process_packet (
    23   POSIX_Condition_variables_MP_Remote_operations  operation,
    24   Objects_Id                        condition_variables_id,
    25   Objects_Name                      name,
    26   Objects_Id                        proxy_id
    27 )
    28 {
    29   (void) POSIX_MP_NOT_IMPLEMENTED();
    30 }
    31 
    32 void _POSIX_Condition_variables_MP_Send_extract_proxy(
    33   Thread_Control *the_thread
    34 )
    35 {
    36   (void) POSIX_MP_NOT_IMPLEMENTED();
    37 }
    38 #endif
    39 
    40 /*
    41  *  END OF TEMPORARY
    42  */
    43 
    44 /*PAGE
    45  *
    46  *  The default condition variable attributes structure.
    47  */
    48  
    49 const pthread_condattr_t _POSIX_Condition_variables_Default_attributes = {
    50   TRUE,                      /* is_initialized */
    51   PTHREAD_PROCESS_PRIVATE    /* process_shared */
    52 };
    53  
    5416/*PAGE
    5517 *
     
    8042  );
    8143}
    82 
    83 /*PAGE
    84  *
    85  *  11.4.1 Condition Variable Initialization Attributes,
    86  *            P1003.1c/Draft 10, p. 96
    87  */
    88  
    89 int pthread_condattr_init(
    90   pthread_condattr_t *attr
    91 )
    92 {
    93   if ( !attr )
    94     return EINVAL;
    95 
    96   *attr = _POSIX_Condition_variables_Default_attributes;
    97   return 0;
    98 }
    99  
    100 /*PAGE
    101  *
    102  *  11.4.1 Condition Variable Initialization Attributes,
    103  *            P1003.1c/Draft 10, p. 96
    104  */
    105  
    106 int pthread_condattr_destroy(
    107   pthread_condattr_t *attr
    108 )
    109 {
    110   if ( !attr || attr->is_initialized == FALSE )
    111     return EINVAL;
    112 
    113   attr->is_initialized = FALSE;
    114   return 0;
    115 }
    116  
    117 /*PAGE
    118  *
    119  *  11.4.1 Condition Variable Initialization Attributes,
    120  *            P1003.1c/Draft 10, p. 96
    121  */
    122  
    123 int pthread_condattr_getpshared(
    124   const pthread_condattr_t *attr,
    125   int                      *pshared
    126 )
    127 {
    128   if ( !attr )
    129     return EINVAL;
    130 
    131   *pshared = attr->process_shared;
    132   return 0;
    133 }
    134  
    135 /*PAGE
    136  *
    137  *  11.4.1 Condition Variable Initialization Attributes,
    138  *            P1003.1c/Draft 10, p. 96
    139  */
    140  
    141 int pthread_condattr_setpshared(
    142   pthread_condattr_t *attr,
    143   int                 pshared
    144 )
    145 {
    146   if ( !attr )
    147     return EINVAL;
    148 
    149   switch ( pshared ) {
    150     case PTHREAD_PROCESS_SHARED:
    151     case PTHREAD_PROCESS_PRIVATE:
    152       attr->process_shared = pshared;
    153       return 0;
    154 
    155     default:
    156       return EINVAL;
    157   }
    158 }
    159  
    160 /*PAGE
    161  *
    162  *  11.4.2 Initializing and Destroying a Condition Variable,
    163  *         P1003.1c/Draft 10, p. 87
    164  */
    165  
    166 int pthread_cond_init(
    167   pthread_cond_t           *cond,
    168   const pthread_condattr_t *attr
    169 )
    170 {
    171   POSIX_Condition_variables_Control   *the_cond;
    172   const pthread_condattr_t            *the_attr;
    173  
    174   if ( attr ) the_attr = attr;
    175   else        the_attr = &_POSIX_Condition_variables_Default_attributes;
    176  
    177   /*
    178    *  XXX: Be careful about attributes when global!!!
    179    */
    180  
    181   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
    182     return POSIX_MP_NOT_IMPLEMENTED();
    183  
    184   if ( !the_attr->is_initialized )
    185     return EINVAL;
    186  
    187   _Thread_Disable_dispatch();
    188  
    189   the_cond = _POSIX_Condition_variables_Allocate();
    190  
    191   if ( !the_cond ) {
    192     _Thread_Enable_dispatch();
    193     return ENOMEM;
    194   }
    195  
    196 #if defined(RTEMS_MULTIPROCESSING)
    197   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&
    198      !( _Objects_MP_Allocate_and_open( &_POSIX_Condition_variables_Information,
    199                 0, the_cond->Object.id, FALSE ) ) ) {
    200     _POSIX_Condition_variables_Free( the_cond );
    201     _Thread_Enable_dispatch();
    202     return EAGAIN;
    203   }
    204 #endif
    205  
    206   the_cond->process_shared  = the_attr->process_shared;
    207 
    208   the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
    209 
    210 /* XXX some more initialization might need to go here */
    211   _Thread_queue_Initialize(
    212     &the_cond->Wait_queue,
    213     OBJECTS_POSIX_CONDITION_VARIABLES,
    214     THREAD_QUEUE_DISCIPLINE_FIFO,
    215     STATES_WAITING_FOR_CONDITION_VARIABLE,
    216 #if defined(RTEMS_MULTIPROCESSING)
    217     _POSIX_Condition_variables_MP_Send_extract_proxy,
    218 #else
    219     NULL,
    220 #endif
    221     ETIMEDOUT
    222   );
    223 
    224   _Objects_Open(
    225     &_POSIX_Condition_variables_Information,
    226     &the_cond->Object,
    227     0
    228   );
    229  
    230   *cond = the_cond->Object.id;
    231  
    232 #if defined(RTEMS_MULTIPROCESSING)
    233   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
    234     _POSIX_Condition_variables_MP_Send_process_packet(
    235       POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_CREATE,
    236       the_cond->Object.id,
    237       0,                         /* Name not used */
    238       0                          /* Not used */
    239     );
    240 #endif
    241  
    242   _Thread_Enable_dispatch();
    243 
    244   return 0;
    245 }
    246  
    247 /*PAGE
    248  *
    249  *  11.4.2 Initializing and Destroying a Condition Variable,
    250  *         P1003.1c/Draft 10, p. 87
    251  */
    252  
    253 int pthread_cond_destroy(
    254   pthread_cond_t           *cond
    255 )
    256 {
    257   register POSIX_Condition_variables_Control *the_cond;
    258   Objects_Locations                           location;
    259  
    260   the_cond = _POSIX_Condition_variables_Get( cond, &location );
    261   switch ( location ) {
    262     case OBJECTS_REMOTE:
    263 #if defined(RTEMS_MULTIPROCESSING)
    264       _Thread_Dispatch();
    265       return POSIX_MP_NOT_IMPLEMENTED();
    266       return EINVAL;
    267 #endif
    268 
    269     case OBJECTS_ERROR:
    270       return EINVAL;
    271 
    272 
    273     case OBJECTS_LOCAL:
    274  
    275       if ( _Thread_queue_First( &the_cond->Wait_queue ) ) {
    276         _Thread_Enable_dispatch();
    277         return EBUSY;
    278       }
    279  
    280       _Objects_Close(
    281         &_POSIX_Condition_variables_Information,
    282         &the_cond->Object
    283       );
    284  
    285       _POSIX_Condition_variables_Free( the_cond );
    286  
    287 #if defined(RTEMS_MULTIPROCESSING)
    288       if ( the_cond->process_shared == PTHREAD_PROCESS_SHARED ) {
    289  
    290         _Objects_MP_Close(
    291           &_POSIX_Condition_variables_Information,
    292           the_cond->Object.id
    293         );
    294  
    295         _POSIX_Condition_variables_MP_Send_process_packet(
    296           POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_DELETE,
    297           the_cond->Object.id,
    298           0,                         /* Not used */
    299           0                          /* Not used */
    300         );
    301       }
    302 #endif
    303       _Thread_Enable_dispatch();
    304       return 0;
    305   }
    306   return POSIX_BOTTOM_REACHED();
    307 }
    308  
    309 /*PAGE
    310  *
    311  *  _POSIX_Condition_variables_Signal_support
    312  *
    313  *  A support routine which implements guts of the broadcast and single task
    314  *  wake up version of the "signal" operation.
    315  */
    316  
    317 int _POSIX_Condition_variables_Signal_support(
    318   pthread_cond_t            *cond,
    319   boolean                    is_broadcast
    320 )
    321 {
    322   register POSIX_Condition_variables_Control *the_cond;
    323   Objects_Locations                           location;
    324   Thread_Control                             *the_thread;
    325  
    326   the_cond = _POSIX_Condition_variables_Get( cond, &location );
    327   switch ( location ) {
    328     case OBJECTS_REMOTE:
    329 #if defined(RTEMS_MULTIPROCESSING)
    330       _Thread_Dispatch();
    331       return POSIX_MP_NOT_IMPLEMENTED();
    332       return EINVAL;
    333 #endif
    334 
    335     case OBJECTS_ERROR:
    336       return EINVAL;
    337     case OBJECTS_LOCAL:
    338  
    339       do {
    340         the_thread = _Thread_queue_Dequeue( &the_cond->Wait_queue );
    341         if ( !the_thread )
    342           the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
    343       } while ( is_broadcast && the_thread );
    344 
    345       _Thread_Enable_dispatch();
    346 
    347       return 0;
    348   }
    349   return POSIX_BOTTOM_REACHED();
    350 }
    351 
    352 /*PAGE
    353  *
    354  *  11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
    355  */
    356  
    357 int pthread_cond_signal(
    358   pthread_cond_t   *cond
    359 )
    360 {
    361   return _POSIX_Condition_variables_Signal_support( cond, FALSE );
    362 }
    363  
    364 /*PAGE
    365  *
    366  *  11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
    367  */
    368  
    369 int pthread_cond_broadcast(
    370   pthread_cond_t   *cond
    371 )
    372 {
    373   return _POSIX_Condition_variables_Signal_support( cond, TRUE );
    374 }
    375  
    376 /*PAGE
    377  *
    378  *  _POSIX_Condition_variables_Wait_support
    379  *
    380  *  A support routine which implements guts of the blocking, non-blocking, and
    381  *  timed wait version of condition variable wait routines.
    382  */
    383  
    384 int _POSIX_Condition_variables_Wait_support(
    385   pthread_cond_t            *cond,
    386   pthread_mutex_t           *mutex,
    387   Watchdog_Interval          timeout,
    388   boolean                    already_timedout
    389 )
    390 {
    391   register POSIX_Condition_variables_Control *the_cond;
    392   Objects_Locations                           location;
    393   int                                         status;
    394   int                                         mutex_status;
    395  
    396   if ( !_POSIX_Mutex_Get( mutex, &location ) ) {
    397      return EINVAL;
    398   }
    399 
    400   _Thread_Unnest_dispatch();
    401 
    402   the_cond = _POSIX_Condition_variables_Get( cond, &location );
    403   switch ( location ) {
    404     case OBJECTS_REMOTE:
    405 #if defined(RTEMS_MULTIPROCESSING)
    406       _Thread_Dispatch();
    407       return POSIX_MP_NOT_IMPLEMENTED();
    408       return EINVAL;
    409 #endif
    410     case OBJECTS_ERROR:
    411       return EINVAL;
    412     case OBJECTS_LOCAL:
    413  
    414       if ( the_cond->Mutex && ( the_cond->Mutex != *mutex ) ) {
    415         _Thread_Enable_dispatch();
    416         return EINVAL;
    417       }
    418  
    419       (void) pthread_mutex_unlock( mutex );
    420 /* XXX ignore this for now  since behavior is undefined
    421       if ( mutex_status ) {
    422         _Thread_Enable_dispatch();
    423         return EINVAL;
    424       }
    425 */
    426 
    427       if ( !already_timedout ) {
    428         the_cond->Mutex = *mutex;
    429  
    430         _Thread_queue_Enter_critical_section( &the_cond->Wait_queue );
    431         _Thread_Executing->Wait.return_code = 0;
    432         _Thread_Executing->Wait.queue       = &the_cond->Wait_queue;
    433         _Thread_Executing->Wait.id          = *cond;
    434 
    435         _Thread_queue_Enqueue( &the_cond->Wait_queue, timeout );
    436 
    437         _Thread_Enable_dispatch();
    438 
    439         /*
    440          *  Switch ourself out because we blocked as a result of the
    441          *  _Thread_queue_Enqueue.
    442          */
    443 
    444         status = _Thread_Executing->Wait.return_code;
    445         if ( status && status != ETIMEDOUT )
    446           return status;
    447 
    448       } else {
    449         _Thread_Enable_dispatch();
    450         status = ETIMEDOUT;
    451       }
    452 
    453       /*
    454        *  When we get here the dispatch disable level is 0.
    455        */
    456 
    457       mutex_status = pthread_mutex_lock( mutex );
    458       if ( mutex_status )
    459         return EINVAL;
    460    
    461       return status;
    462   }
    463   return POSIX_BOTTOM_REACHED();
    464 }
    465 
    466 /*PAGE
    467  *
    468  *  11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
    469  */
    470  
    471 int pthread_cond_wait(
    472   pthread_cond_t     *cond,
    473   pthread_mutex_t    *mutex
    474 )
    475 {
    476   return _POSIX_Condition_variables_Wait_support(
    477     cond,
    478     mutex,
    479     THREAD_QUEUE_WAIT_FOREVER,
    480     FALSE
    481   );
    482 }
    483  
    484 /*PAGE
    485  *
    486  *  11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
    487  */
    488  
    489 int pthread_cond_timedwait(
    490   pthread_cond_t        *cond,
    491   pthread_mutex_t       *mutex,
    492   const struct timespec *abstime
    493 )
    494 {
    495   Watchdog_Interval timeout;
    496   struct timespec   current_time;
    497   struct timespec   difference;
    498   boolean           already_timedout = FALSE;
    499 
    500   if ( !abstime )
    501     return EINVAL;
    502 
    503   /*
    504    *  The abstime is a walltime.  We turn it into an interval.
    505    */
    506 
    507   (void) clock_gettime( CLOCK_REALTIME, &current_time );
    508 
    509   /* XXX probably some error checking should go here */
    510 
    511   _POSIX_Timespec_subtract( &current_time, abstime, &difference );
    512 
    513   if ( ( difference.tv_sec < 0 ) || ( ( difference.tv_sec == 0 ) &&
    514        ( difference.tv_nsec < 0 ) ) )
    515     already_timedout = TRUE;   
    516 
    517   timeout = _POSIX_Timespec_to_interval( &difference );
    518 
    519   return _POSIX_Condition_variables_Wait_support(
    520     cond,
    521     mutex,
    522     timeout,
    523     already_timedout
    524   );
    525 }
Note: See TracChangeset for help on using the changeset viewer.