Changeset 799c767 in rtems


Ignore:
Timestamp:
Nov 2, 1999, 6:00:15 PM (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
98dca75
Parents:
ee979cd
Message:

Split the POSIX semaphore manager into multiple files.

Files:
28 added
7 edited

Legend:

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

    ree979cd r799c767  
    8181);
    8282
     83boolean _POSIX_signals_Check_signal(
     84  POSIX_API_Control  *api,
     85  int                 signo,
     86  boolean             is_global
     87);
     88
    8389boolean _POSIX_signals_Clear_signals(
    8490  POSIX_API_Control  *api,
  • c/src/exec/posix/include/rtems/posix/semaphore.h

    ree979cd r799c767  
    2222#endif
    2323
     24#include <semaphore.h>
    2425#include <rtems/score/coresem.h>
    2526
     
    114115
    115116/*
     117 *  _POSIX_Semaphore_Create_support
     118 *
     119 *  DESCRIPTION:
     120 *
     121 *  This routine supports the sem_init and sem_open routines.
     122 */
     123
     124int _POSIX_Semaphore_Create_support(
     125  const char                *name,
     126  int                        pshared,
     127  unsigned int               value,
     128  POSIX_Semaphore_Control  **the_sem
     129);
     130
     131/*
     132 *  _POSIX_Semaphore_Wait_support
     133 *
     134 *  DESCRIPTION:
     135 *
     136 *  This routine supports the sem_wait, sem_trywait, and sem_timedwait
     137 *  services.
     138 */
     139
     140int _POSIX_Semaphore_Wait_support(
     141  sem_t              *sem,
     142  boolean             blocking,
     143  Watchdog_Interval   timeout
     144);
     145
     146/*
    116147 *  _POSIX_Semaphore_Name_to_id
    117148 *
    118149 *  DESCRIPTION:
    119150 *
    120  *  XXX
     151 *  This routine performs name to id translation.
    121152 */
    122153
  • c/src/exec/posix/src/Makefile.in

    ree979cd r799c767  
    1515
    1616# following are semi-implemented and untested
    17 # C_PIECES=aio cancel devctl intr mqueue semaphore utsname
     17# C_PIECES=aio cancel devctl intr utsname
    1818
    1919# These are really in the stand but not really functional
    20 BUILD_FOR_NOW_C_PIECES = aio cancel mqueue semaphore utsname
     20BUILD_FOR_NOW_C_PIECES = aio cancel utsname
    2121
    2222ENOSYS_C_PIECES = execl execle execlp execv execve execvp fork pthreadatfork \
     
    5454    sigwait sigwaitinfo signal_2
    5555
     56SEMAPHORE_C_PIECES= semaphore semaphorecreatesupp semaphoredeletesupp \
     57    semaphoremp semaphorenametoid semaphorewaitsupp semdestroy \
     58    semgetvalue seminit semopen sempost semtimedwait semtrywait \
     59    semunlink semwait
     60
    5661C_PIECES = adasupp cond getpid key $(MESSAGE_QUEUE_PIECES) \
    5762    $(MUTEX_C_PIECES) $(PTHREAD_C_PIECES) \
    58     $(PSIGNAL_C_PIECES) ptimer sched time types unistd $(ENOSYS_C_PIECES) \
     63    $(PSIGNAL_C_PIECES) ptimer sched $(SEMAPHORE_C_PIECES) \
     64    time types unistd $(ENOSYS_C_PIECES) \
    5965    $(BUILD_FOR_NOW_C_PIECES)
    6066
  • c/src/exec/posix/src/semaphore.c

    ree979cd r799c767  
    4444  );
    4545}
    46 
    47 /*PAGE
    48  *
    49  *  _POSIX_Semaphore_Create_support
    50  */
    51 
    52 int _POSIX_Semaphore_Create_support(
    53   const char                *name,
    54   int                        pshared,
    55   unsigned int               value,
    56   POSIX_Semaphore_Control  **the_sem
    57 )
    58 {
    59   POSIX_Semaphore_Control   *the_semaphore;
    60   CORE_semaphore_Attributes *the_sem_attr;
    61 
    62   _Thread_Disable_dispatch();
    63  
    64   /* Sharing semaphores among processes is not currently supported */
    65   if (pshared != 0) {
    66     _Thread_Enable_dispatch();
    67     set_errno_and_return_minus_one( ENOSYS );
    68   }
    69 
    70   the_semaphore = _POSIX_Semaphore_Allocate();
    71  
    72   if ( !the_semaphore ) {
    73     _Thread_Enable_dispatch();
    74     set_errno_and_return_minus_one( ENOSPC );
    75   }
    76  
    77 #if defined(RTEMS_MULTIPROCESSING)
    78   if ( pshared == PTHREAD_PROCESS_SHARED &&
    79        !( _Objects_MP_Allocate_and_open( &_POSIX_Semaphore_Information, 0,
    80                             the_semaphore->Object.id, FALSE ) ) ) {
    81     _POSIX_Semaphore_Free( the_semaphore );
    82     _Thread_Enable_dispatch();
    83     set_errno_and_return_minus_one( EAGAIN );
    84   }
    85 #endif
    86  
    87   the_semaphore->process_shared  = pshared;
    88 
    89   if ( name ) {
    90     the_semaphore->named = TRUE;
    91     the_semaphore->open_count = 1;
    92     the_semaphore->linked = TRUE;
    93   }
    94   else
    95     the_semaphore->named = FALSE;
    96 
    97   the_sem_attr = &the_semaphore->Semaphore.Attributes;
    98  
    99   /* XXX
    100    *
    101    *  Note should this be based on the current scheduling policy?
    102    */
    103 
    104   the_sem_attr->discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
    105 
    106   /*
    107    *  This effectively disables limit checking.
    108    */
    109 
    110   the_sem_attr->maximum_count = 0xFFFFFFFF;
    111 
    112   _CORE_semaphore_Initialize(
    113     &the_semaphore->Semaphore,
    114     OBJECTS_POSIX_SEMAPHORES,
    115     the_sem_attr,
    116     value,
    117     0      /* XXX - proxy_extract_callout is unused */
    118   );
    119  
    120   /* XXX - need Names to be a string!!! */
    121   _Objects_Open(
    122     &_POSIX_Semaphore_Information,
    123     &the_semaphore->Object,
    124     (char *) name
    125   );
    126  
    127   *the_sem = the_semaphore;
    128  
    129 #if defined(RTEMS_MULTIPROCESSING)
    130   if ( pshared == PTHREAD_PROCESS_SHARED )
    131     _POSIX_Semaphore_MP_Send_process_packet(
    132       POSIX_SEMAPHORE_MP_ANNOUNCE_CREATE,
    133       the_semaphore->Object.id,
    134       (char *) name,
    135       0                /* proxy id - Not used */
    136     );
    137 #endif
    138  
    139   _Thread_Enable_dispatch();
    140   return 0;
    141 }
    142 
    143 
    144 /*PAGE
    145  *
    146  *  11.2.1 Initialize an Unnamed Semaphore, P1003.1b-1993, p.219
    147  */
    148 
    149 int sem_init(
    150   sem_t         *sem,
    151   int            pshared,
    152   unsigned int   value
    153 )
    154 {
    155   int                        status;
    156   POSIX_Semaphore_Control   *the_semaphore;
    157 
    158   status = _POSIX_Semaphore_Create_support(
    159     NULL,
    160     pshared,
    161     value,
    162     &the_semaphore
    163   );
    164    
    165   if ( status != -1 )
    166     *sem = the_semaphore->Object.id;
    167 
    168   return status;
    169 }
    170 
    171 /*PAGE
    172  *
    173  *  11.2.2 Destroy an Unnamed Semaphore, P1003.1b-1993, p.220
    174  */
    175 
    176 int sem_destroy(
    177   sem_t *sem
    178 )
    179 {
    180   register POSIX_Semaphore_Control *the_semaphore;
    181   Objects_Locations                 location;
    182  
    183   the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    184   switch ( location ) {
    185     case OBJECTS_ERROR:
    186       set_errno_and_return_minus_one( EINVAL );
    187     case OBJECTS_REMOTE:
    188       _Thread_Dispatch();
    189       return POSIX_MP_NOT_IMPLEMENTED();
    190       set_errno_and_return_minus_one( EINVAL );
    191     case OBJECTS_LOCAL:
    192       /*
    193        *  Undefined operation on a named semaphore.
    194        */
    195 
    196       if ( the_semaphore->named == TRUE ) {
    197         set_errno_and_return_minus_one( EINVAL );
    198       }
    199  
    200       _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
    201  
    202       _CORE_semaphore_Flush(
    203         &the_semaphore->Semaphore,
    204 #if defined(RTEMS_MULTIPROCESSING)
    205         _POSIX_Semaphore_MP_Send_object_was_deleted,
    206 #else
    207         NULL,
    208 #endif
    209         -1  /* XXX should also seterrno -> EINVAL */
    210       );
    211  
    212       _POSIX_Semaphore_Free( the_semaphore );
    213  
    214 #if defined(RTEMS_MULTIPROCESSING)
    215       if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
    216  
    217         _Objects_MP_Close(
    218           &_POSIX_Semaphore_Information,
    219           the_semaphore->Object.id
    220         );
    221  
    222         _POSIX_Semaphore_MP_Send_process_packet(
    223           POSIX_SEMAPHORE_MP_ANNOUNCE_DELETE,
    224           the_semaphore->Object.id,
    225           0,                         /* Not used */
    226           0                          /* Not used */
    227         );
    228       }
    229 #endif
    230       _Thread_Enable_dispatch();
    231       return 0;
    232   }
    233   return POSIX_BOTTOM_REACHED();
    234 }
    235 
    236 /*PAGE
    237  *
    238  *  11.2.3 Initialize/Open a Named Semaphore, P1003.1b-1993, p.221
    239  *
    240  *  NOTE: When oflag is O_CREAT, then optional third and fourth
    241  *        parameters must be present.
    242  */
    243 
    244 sem_t *sem_open(
    245   const char *name,
    246   int         oflag,
    247   ...
    248   /* mode_t mode, */
    249   /* unsigned int value */
    250 )
    251 {
    252   va_list                    arg;
    253   mode_t                     mode;
    254   unsigned int               value = 0;
    255   int                        status;
    256   Objects_Id                 the_semaphore_id;
    257   POSIX_Semaphore_Control   *the_semaphore;
    258   Objects_Locations          location;
    259  
    260 
    261   if ( oflag & O_CREAT ) {
    262     va_start(arg, oflag);
    263     /*mode = (mode_t) va_arg( arg, mode_t * );*/
    264     mode = va_arg( arg, mode_t );
    265     /*value = (unsigned int) va_arg( arg, unsigned int * );*/
    266     value = va_arg( arg, unsigned int );
    267     va_end(arg);
    268   }
    269 
    270   status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id );
    271    
    272   /*
    273    *  If the name to id translation worked, then the semaphore exists
    274    *  and we can just return a pointer to the id.  Otherwise we may
    275    *  need to check to see if this is a "semaphore does not exist"
    276    *  or some other miscellaneous error on the name.
    277    */
    278 
    279   if ( status ) {
    280 
    281     if ( status == EINVAL ) {      /* name -> ID translation failed */
    282       if ( !(oflag & O_CREAT) ) {  /* willing to create it? */
    283         set_errno_and_return_minus_one_cast( ENOENT, sem_t * );
    284       }
    285       /* we are willing to create it */
    286     }
    287     /* some type of error */
    288     /*set_errno_and_return_minus_one_cast( status, sem_t * );*/
    289 
    290   } else {                /* name -> ID translation succeeded */
    291 
    292     if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
    293       set_errno_and_return_minus_one_cast( EEXIST, sem_t * );
    294     }
    295 
    296     /*
    297      * XXX In this case we need to do an ID->pointer conversion to
    298      *     check the mode.   This is probably a good place for a subroutine.
    299      */
    300 
    301     the_semaphore = _POSIX_Semaphore_Get( &the_semaphore_id, &location );
    302     the_semaphore->open_count += 1;
    303 
    304     return (sem_t *)&the_semaphore->Object.id;
    305 
    306   }
    307  
    308   /* XXX verify this comment...
    309    *
    310    *  At this point, the semaphore does not exist and everything has been
    311    *  checked. We should go ahead and create a semaphore.
    312    */
    313 
    314   status = _POSIX_Semaphore_Create_support(
    315     name,
    316     FALSE,         /* not shared across processes */
    317     value,
    318     &the_semaphore
    319   );
    320  
    321   if ( status == -1 )
    322     return (sem_t *) -1;
    323 
    324   return (sem_t *) &the_semaphore->Object.id;
    325  
    326 }
    327 
    328 /*PAGE
    329  *
    330  *  _POSIX_Semaphore_Delete
    331  */
    332 
    333 void _POSIX_Semaphore_Delete(
    334   POSIX_Semaphore_Control *the_semaphore
    335 )
    336 {
    337   if ( !the_semaphore->linked && !the_semaphore->open_count ) {
    338     _POSIX_Semaphore_Free( the_semaphore );
    339 
    340 #if defined(RTEMS_MULTIPROCESSING)
    341     if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
    342 
    343       _Objects_MP_Close(
    344         &_POSIX_Semaphore_Information,
    345         the_semaphore->Object.id
    346       );
    347 
    348       _POSIX_Semaphore_MP_Send_process_packet(
    349         POSIX_SEMAPHORE_MP_ANNOUNCE_DELETE,
    350         the_semaphore->Object.id,
    351         0,                         /* Not used */
    352         0                          /* Not used */
    353       );
    354     }
    355 #endif
    356 
    357   }
    358 }
    359 
    360 /*PAGE
    361  *
    362  *  11.2.4 Close a Named Semaphore, P1003.1b-1993, p.224
    363  */
    364 
    365 int sem_close(
    366   sem_t *sem
    367 )
    368 {
    369   register POSIX_Semaphore_Control *the_semaphore;
    370   Objects_Locations                 location;
    371  
    372   the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    373   switch ( location ) {
    374     case OBJECTS_ERROR:
    375       set_errno_and_return_minus_one( EINVAL );
    376     case OBJECTS_REMOTE:
    377       _Thread_Dispatch();
    378       return POSIX_MP_NOT_IMPLEMENTED();
    379       set_errno_and_return_minus_one( EINVAL );
    380     case OBJECTS_LOCAL:
    381       the_semaphore->open_count -= 1;
    382       _POSIX_Semaphore_Delete( the_semaphore );
    383       _Thread_Enable_dispatch();
    384       return 0;
    385   }
    386   return POSIX_BOTTOM_REACHED();
    387 }
    388 
    389 /*PAGE
    390  *
    391  *  11.2.5 Remove a Named Semaphore, P1003.1b-1993, p.225
    392  */
    393 
    394 int sem_unlink(
    395   const char *name
    396 )
    397 {
    398   int  status;
    399   register POSIX_Semaphore_Control *the_semaphore;
    400   Objects_Id                        the_semaphore_id;
    401   Objects_Locations                 location;
    402  
    403   status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id );
    404    
    405   if ( !status )
    406     set_errno_and_return_minus_one( status );
    407 
    408   the_semaphore = _POSIX_Semaphore_Get( &the_semaphore_id, &location );
    409   switch ( location ) {
    410     case OBJECTS_ERROR:
    411       set_errno_and_return_minus_one( EINVAL );
    412     case OBJECTS_REMOTE:
    413       _Thread_Dispatch();
    414       return POSIX_MP_NOT_IMPLEMENTED();
    415       set_errno_and_return_minus_one( EINVAL );
    416     case OBJECTS_LOCAL:
    417 
    418 #if defined(RTEMS_MULTIPROCESSING)
    419       if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
    420         _Objects_MP_Close(
    421           &_POSIX_Semaphore_Information,
    422           the_semaphore->Object.id
    423         );
    424       }
    425 #endif
    426 
    427       the_semaphore->linked = FALSE;
    428 
    429       _POSIX_Semaphore_Delete( the_semaphore );
    430 
    431       _Thread_Enable_dispatch();
    432       return 0;
    433   }
    434   return POSIX_BOTTOM_REACHED();
    435 }
    436 
    437 /*PAGE
    438  *
    439  *  _POSIX_Semaphore_Wait_support
    440  */
    441 
    442 int _POSIX_Semaphore_Wait_support(
    443   sem_t              *sem,
    444   boolean             blocking,
    445   Watchdog_Interval   timeout
    446 )
    447 {
    448   register POSIX_Semaphore_Control *the_semaphore;
    449   Objects_Locations                 location;
    450   int                               code;
    451  
    452   the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    453   switch ( location ) {
    454     case OBJECTS_ERROR:
    455       set_errno_and_return_minus_one( EINVAL );
    456     case OBJECTS_REMOTE:
    457       _Thread_Dispatch();
    458       return POSIX_MP_NOT_IMPLEMENTED();
    459       set_errno_and_return_minus_one( EINVAL );
    460     case OBJECTS_LOCAL:
    461       _CORE_semaphore_Seize(
    462         &the_semaphore->Semaphore,
    463         the_semaphore->Object.id,
    464         blocking,
    465         timeout
    466       );
    467       _Thread_Enable_dispatch();
    468       code = _Thread_Executing->Wait.return_code;
    469       switch (_Thread_Executing->Wait.return_code) {
    470         case 1:
    471           errno = EAGAIN;
    472           code = -1;
    473           break;
    474         case 3:
    475           errno = ETIMEDOUT;
    476           code = -1;
    477           break;
    478       }
    479 
    480       /*return _Thread_Executing->Wait.return_code;*/
    481       return code;
    482   }
    483   return POSIX_BOTTOM_REACHED();
    484 }
    485 
    486 /*PAGE
    487  *
    488  *  11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
    489  *
    490  *  NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
    491  */
    492 
    493 int sem_wait(
    494   sem_t *sem
    495 )
    496 {
    497   return _POSIX_Semaphore_Wait_support( sem, TRUE, THREAD_QUEUE_WAIT_FOREVER );
    498 }
    499 
    500 /*PAGE
    501  *
    502  *  11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
    503  *
    504  *  NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
    505  */
    506 
    507 int sem_trywait(
    508   sem_t *sem
    509 )
    510 {
    511   return _POSIX_Semaphore_Wait_support( sem, FALSE, THREAD_QUEUE_WAIT_FOREVER );
    512 }
    513 
    514 /*PAGE
    515  *
    516  *  11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
    517  *
    518  *  NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
    519  */
    520 
    521 int sem_timedwait(
    522   sem_t                 *sem,
    523   const struct timespec *timeout
    524 )
    525 {
    526   return _POSIX_Semaphore_Wait_support(
    527     sem,
    528     TRUE,
    529     _POSIX_Timespec_to_interval( timeout )
    530   );
    531 }
    532 
    533 /*PAGE
    534  *
    535  *  11.2.7 Unlock a Semaphore, P1003.1b-1993, p.227
    536  */
    537 
    538 void POSIX_Semaphore_MP_support(
    539   Thread_Control *the_thread,
    540   Objects_Id      id
    541 )
    542 {
    543   (void) POSIX_MP_NOT_IMPLEMENTED();
    544 }
    545  
    546 
    547 int sem_post(
    548   sem_t  *sem
    549 )
    550 {
    551   register POSIX_Semaphore_Control *the_semaphore;
    552   Objects_Locations                 location;
    553  
    554   the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    555   switch ( location ) {
    556     case OBJECTS_ERROR:
    557       set_errno_and_return_minus_one( EINVAL );
    558     case OBJECTS_REMOTE:
    559       _Thread_Dispatch();
    560       return POSIX_MP_NOT_IMPLEMENTED();
    561       set_errno_and_return_minus_one( EINVAL );
    562     case OBJECTS_LOCAL:
    563       _CORE_semaphore_Surrender(
    564         &the_semaphore->Semaphore,
    565         the_semaphore->Object.id,
    566 #if defined(RTEMS_MULTIPROCESSING)
    567         POSIX_Semaphore_MP_support
    568 #else
    569         NULL
    570 #endif
    571       );
    572       _Thread_Enable_dispatch();
    573       return 0;
    574   }
    575   return POSIX_BOTTOM_REACHED();
    576 }
    577 
    578 /*PAGE
    579  *
    580  *  11.2.8 Get the Value of a Semaphore, P1003.1b-1993, p.229
    581  */
    582 
    583 int sem_getvalue(
    584   sem_t  *sem,
    585   int    *sval
    586 )
    587 {
    588   register POSIX_Semaphore_Control *the_semaphore;
    589   Objects_Locations                 location;
    590  
    591   the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    592   switch ( location ) {
    593     case OBJECTS_ERROR:
    594       set_errno_and_return_minus_one( EINVAL );
    595     case OBJECTS_REMOTE:
    596       _Thread_Dispatch();
    597       return POSIX_MP_NOT_IMPLEMENTED();
    598       set_errno_and_return_minus_one( EINVAL );
    599     case OBJECTS_LOCAL:
    600       *sval = _CORE_semaphore_Get_count( &the_semaphore->Semaphore );
    601       _Thread_Enable_dispatch();
    602       return 0;
    603   }
    604   return POSIX_BOTTOM_REACHED();
    605 }
    606 
    607 /*PAGE
    608  *
    609  *  _POSIX_Semaphore_Name_to_id
    610  *
    611  *  XXX
    612  */
    613 
    614 int _POSIX_Semaphore_Name_to_id(
    615   const char          *name,
    616   Objects_Id          *id
    617 )
    618 {
    619   Objects_Name_to_id_errors  status;
    620 
    621   status = _Objects_Name_to_id( &_POSIX_Semaphore_Information, (char *)name, 0, id );
    622 
    623   if ( status == OBJECTS_SUCCESSFUL ) {
    624           return 0;
    625   } else {
    626           return EINVAL;
    627   }
    628 }
    629 
  • cpukit/posix/include/rtems/posix/psignal.h

    ree979cd r799c767  
    8181);
    8282
     83boolean _POSIX_signals_Check_signal(
     84  POSIX_API_Control  *api,
     85  int                 signo,
     86  boolean             is_global
     87);
     88
    8389boolean _POSIX_signals_Clear_signals(
    8490  POSIX_API_Control  *api,
  • cpukit/posix/include/rtems/posix/semaphore.h

    ree979cd r799c767  
    2222#endif
    2323
     24#include <semaphore.h>
    2425#include <rtems/score/coresem.h>
    2526
     
    114115
    115116/*
     117 *  _POSIX_Semaphore_Create_support
     118 *
     119 *  DESCRIPTION:
     120 *
     121 *  This routine supports the sem_init and sem_open routines.
     122 */
     123
     124int _POSIX_Semaphore_Create_support(
     125  const char                *name,
     126  int                        pshared,
     127  unsigned int               value,
     128  POSIX_Semaphore_Control  **the_sem
     129);
     130
     131/*
     132 *  _POSIX_Semaphore_Wait_support
     133 *
     134 *  DESCRIPTION:
     135 *
     136 *  This routine supports the sem_wait, sem_trywait, and sem_timedwait
     137 *  services.
     138 */
     139
     140int _POSIX_Semaphore_Wait_support(
     141  sem_t              *sem,
     142  boolean             blocking,
     143  Watchdog_Interval   timeout
     144);
     145
     146/*
    116147 *  _POSIX_Semaphore_Name_to_id
    117148 *
    118149 *  DESCRIPTION:
    119150 *
    120  *  XXX
     151 *  This routine performs name to id translation.
    121152 */
    122153
  • cpukit/posix/src/semaphore.c

    ree979cd r799c767  
    4444  );
    4545}
    46 
    47 /*PAGE
    48  *
    49  *  _POSIX_Semaphore_Create_support
    50  */
    51 
    52 int _POSIX_Semaphore_Create_support(
    53   const char                *name,
    54   int                        pshared,
    55   unsigned int               value,
    56   POSIX_Semaphore_Control  **the_sem
    57 )
    58 {
    59   POSIX_Semaphore_Control   *the_semaphore;
    60   CORE_semaphore_Attributes *the_sem_attr;
    61 
    62   _Thread_Disable_dispatch();
    63  
    64   /* Sharing semaphores among processes is not currently supported */
    65   if (pshared != 0) {
    66     _Thread_Enable_dispatch();
    67     set_errno_and_return_minus_one( ENOSYS );
    68   }
    69 
    70   the_semaphore = _POSIX_Semaphore_Allocate();
    71  
    72   if ( !the_semaphore ) {
    73     _Thread_Enable_dispatch();
    74     set_errno_and_return_minus_one( ENOSPC );
    75   }
    76  
    77 #if defined(RTEMS_MULTIPROCESSING)
    78   if ( pshared == PTHREAD_PROCESS_SHARED &&
    79        !( _Objects_MP_Allocate_and_open( &_POSIX_Semaphore_Information, 0,
    80                             the_semaphore->Object.id, FALSE ) ) ) {
    81     _POSIX_Semaphore_Free( the_semaphore );
    82     _Thread_Enable_dispatch();
    83     set_errno_and_return_minus_one( EAGAIN );
    84   }
    85 #endif
    86  
    87   the_semaphore->process_shared  = pshared;
    88 
    89   if ( name ) {
    90     the_semaphore->named = TRUE;
    91     the_semaphore->open_count = 1;
    92     the_semaphore->linked = TRUE;
    93   }
    94   else
    95     the_semaphore->named = FALSE;
    96 
    97   the_sem_attr = &the_semaphore->Semaphore.Attributes;
    98  
    99   /* XXX
    100    *
    101    *  Note should this be based on the current scheduling policy?
    102    */
    103 
    104   the_sem_attr->discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
    105 
    106   /*
    107    *  This effectively disables limit checking.
    108    */
    109 
    110   the_sem_attr->maximum_count = 0xFFFFFFFF;
    111 
    112   _CORE_semaphore_Initialize(
    113     &the_semaphore->Semaphore,
    114     OBJECTS_POSIX_SEMAPHORES,
    115     the_sem_attr,
    116     value,
    117     0      /* XXX - proxy_extract_callout is unused */
    118   );
    119  
    120   /* XXX - need Names to be a string!!! */
    121   _Objects_Open(
    122     &_POSIX_Semaphore_Information,
    123     &the_semaphore->Object,
    124     (char *) name
    125   );
    126  
    127   *the_sem = the_semaphore;
    128  
    129 #if defined(RTEMS_MULTIPROCESSING)
    130   if ( pshared == PTHREAD_PROCESS_SHARED )
    131     _POSIX_Semaphore_MP_Send_process_packet(
    132       POSIX_SEMAPHORE_MP_ANNOUNCE_CREATE,
    133       the_semaphore->Object.id,
    134       (char *) name,
    135       0                /* proxy id - Not used */
    136     );
    137 #endif
    138  
    139   _Thread_Enable_dispatch();
    140   return 0;
    141 }
    142 
    143 
    144 /*PAGE
    145  *
    146  *  11.2.1 Initialize an Unnamed Semaphore, P1003.1b-1993, p.219
    147  */
    148 
    149 int sem_init(
    150   sem_t         *sem,
    151   int            pshared,
    152   unsigned int   value
    153 )
    154 {
    155   int                        status;
    156   POSIX_Semaphore_Control   *the_semaphore;
    157 
    158   status = _POSIX_Semaphore_Create_support(
    159     NULL,
    160     pshared,
    161     value,
    162     &the_semaphore
    163   );
    164    
    165   if ( status != -1 )
    166     *sem = the_semaphore->Object.id;
    167 
    168   return status;
    169 }
    170 
    171 /*PAGE
    172  *
    173  *  11.2.2 Destroy an Unnamed Semaphore, P1003.1b-1993, p.220
    174  */
    175 
    176 int sem_destroy(
    177   sem_t *sem
    178 )
    179 {
    180   register POSIX_Semaphore_Control *the_semaphore;
    181   Objects_Locations                 location;
    182  
    183   the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    184   switch ( location ) {
    185     case OBJECTS_ERROR:
    186       set_errno_and_return_minus_one( EINVAL );
    187     case OBJECTS_REMOTE:
    188       _Thread_Dispatch();
    189       return POSIX_MP_NOT_IMPLEMENTED();
    190       set_errno_and_return_minus_one( EINVAL );
    191     case OBJECTS_LOCAL:
    192       /*
    193        *  Undefined operation on a named semaphore.
    194        */
    195 
    196       if ( the_semaphore->named == TRUE ) {
    197         set_errno_and_return_minus_one( EINVAL );
    198       }
    199  
    200       _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
    201  
    202       _CORE_semaphore_Flush(
    203         &the_semaphore->Semaphore,
    204 #if defined(RTEMS_MULTIPROCESSING)
    205         _POSIX_Semaphore_MP_Send_object_was_deleted,
    206 #else
    207         NULL,
    208 #endif
    209         -1  /* XXX should also seterrno -> EINVAL */
    210       );
    211  
    212       _POSIX_Semaphore_Free( the_semaphore );
    213  
    214 #if defined(RTEMS_MULTIPROCESSING)
    215       if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
    216  
    217         _Objects_MP_Close(
    218           &_POSIX_Semaphore_Information,
    219           the_semaphore->Object.id
    220         );
    221  
    222         _POSIX_Semaphore_MP_Send_process_packet(
    223           POSIX_SEMAPHORE_MP_ANNOUNCE_DELETE,
    224           the_semaphore->Object.id,
    225           0,                         /* Not used */
    226           0                          /* Not used */
    227         );
    228       }
    229 #endif
    230       _Thread_Enable_dispatch();
    231       return 0;
    232   }
    233   return POSIX_BOTTOM_REACHED();
    234 }
    235 
    236 /*PAGE
    237  *
    238  *  11.2.3 Initialize/Open a Named Semaphore, P1003.1b-1993, p.221
    239  *
    240  *  NOTE: When oflag is O_CREAT, then optional third and fourth
    241  *        parameters must be present.
    242  */
    243 
    244 sem_t *sem_open(
    245   const char *name,
    246   int         oflag,
    247   ...
    248   /* mode_t mode, */
    249   /* unsigned int value */
    250 )
    251 {
    252   va_list                    arg;
    253   mode_t                     mode;
    254   unsigned int               value = 0;
    255   int                        status;
    256   Objects_Id                 the_semaphore_id;
    257   POSIX_Semaphore_Control   *the_semaphore;
    258   Objects_Locations          location;
    259  
    260 
    261   if ( oflag & O_CREAT ) {
    262     va_start(arg, oflag);
    263     /*mode = (mode_t) va_arg( arg, mode_t * );*/
    264     mode = va_arg( arg, mode_t );
    265     /*value = (unsigned int) va_arg( arg, unsigned int * );*/
    266     value = va_arg( arg, unsigned int );
    267     va_end(arg);
    268   }
    269 
    270   status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id );
    271    
    272   /*
    273    *  If the name to id translation worked, then the semaphore exists
    274    *  and we can just return a pointer to the id.  Otherwise we may
    275    *  need to check to see if this is a "semaphore does not exist"
    276    *  or some other miscellaneous error on the name.
    277    */
    278 
    279   if ( status ) {
    280 
    281     if ( status == EINVAL ) {      /* name -> ID translation failed */
    282       if ( !(oflag & O_CREAT) ) {  /* willing to create it? */
    283         set_errno_and_return_minus_one_cast( ENOENT, sem_t * );
    284       }
    285       /* we are willing to create it */
    286     }
    287     /* some type of error */
    288     /*set_errno_and_return_minus_one_cast( status, sem_t * );*/
    289 
    290   } else {                /* name -> ID translation succeeded */
    291 
    292     if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
    293       set_errno_and_return_minus_one_cast( EEXIST, sem_t * );
    294     }
    295 
    296     /*
    297      * XXX In this case we need to do an ID->pointer conversion to
    298      *     check the mode.   This is probably a good place for a subroutine.
    299      */
    300 
    301     the_semaphore = _POSIX_Semaphore_Get( &the_semaphore_id, &location );
    302     the_semaphore->open_count += 1;
    303 
    304     return (sem_t *)&the_semaphore->Object.id;
    305 
    306   }
    307  
    308   /* XXX verify this comment...
    309    *
    310    *  At this point, the semaphore does not exist and everything has been
    311    *  checked. We should go ahead and create a semaphore.
    312    */
    313 
    314   status = _POSIX_Semaphore_Create_support(
    315     name,
    316     FALSE,         /* not shared across processes */
    317     value,
    318     &the_semaphore
    319   );
    320  
    321   if ( status == -1 )
    322     return (sem_t *) -1;
    323 
    324   return (sem_t *) &the_semaphore->Object.id;
    325  
    326 }
    327 
    328 /*PAGE
    329  *
    330  *  _POSIX_Semaphore_Delete
    331  */
    332 
    333 void _POSIX_Semaphore_Delete(
    334   POSIX_Semaphore_Control *the_semaphore
    335 )
    336 {
    337   if ( !the_semaphore->linked && !the_semaphore->open_count ) {
    338     _POSIX_Semaphore_Free( the_semaphore );
    339 
    340 #if defined(RTEMS_MULTIPROCESSING)
    341     if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
    342 
    343       _Objects_MP_Close(
    344         &_POSIX_Semaphore_Information,
    345         the_semaphore->Object.id
    346       );
    347 
    348       _POSIX_Semaphore_MP_Send_process_packet(
    349         POSIX_SEMAPHORE_MP_ANNOUNCE_DELETE,
    350         the_semaphore->Object.id,
    351         0,                         /* Not used */
    352         0                          /* Not used */
    353       );
    354     }
    355 #endif
    356 
    357   }
    358 }
    359 
    360 /*PAGE
    361  *
    362  *  11.2.4 Close a Named Semaphore, P1003.1b-1993, p.224
    363  */
    364 
    365 int sem_close(
    366   sem_t *sem
    367 )
    368 {
    369   register POSIX_Semaphore_Control *the_semaphore;
    370   Objects_Locations                 location;
    371  
    372   the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    373   switch ( location ) {
    374     case OBJECTS_ERROR:
    375       set_errno_and_return_minus_one( EINVAL );
    376     case OBJECTS_REMOTE:
    377       _Thread_Dispatch();
    378       return POSIX_MP_NOT_IMPLEMENTED();
    379       set_errno_and_return_minus_one( EINVAL );
    380     case OBJECTS_LOCAL:
    381       the_semaphore->open_count -= 1;
    382       _POSIX_Semaphore_Delete( the_semaphore );
    383       _Thread_Enable_dispatch();
    384       return 0;
    385   }
    386   return POSIX_BOTTOM_REACHED();
    387 }
    388 
    389 /*PAGE
    390  *
    391  *  11.2.5 Remove a Named Semaphore, P1003.1b-1993, p.225
    392  */
    393 
    394 int sem_unlink(
    395   const char *name
    396 )
    397 {
    398   int  status;
    399   register POSIX_Semaphore_Control *the_semaphore;
    400   Objects_Id                        the_semaphore_id;
    401   Objects_Locations                 location;
    402  
    403   status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id );
    404    
    405   if ( !status )
    406     set_errno_and_return_minus_one( status );
    407 
    408   the_semaphore = _POSIX_Semaphore_Get( &the_semaphore_id, &location );
    409   switch ( location ) {
    410     case OBJECTS_ERROR:
    411       set_errno_and_return_minus_one( EINVAL );
    412     case OBJECTS_REMOTE:
    413       _Thread_Dispatch();
    414       return POSIX_MP_NOT_IMPLEMENTED();
    415       set_errno_and_return_minus_one( EINVAL );
    416     case OBJECTS_LOCAL:
    417 
    418 #if defined(RTEMS_MULTIPROCESSING)
    419       if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
    420         _Objects_MP_Close(
    421           &_POSIX_Semaphore_Information,
    422           the_semaphore->Object.id
    423         );
    424       }
    425 #endif
    426 
    427       the_semaphore->linked = FALSE;
    428 
    429       _POSIX_Semaphore_Delete( the_semaphore );
    430 
    431       _Thread_Enable_dispatch();
    432       return 0;
    433   }
    434   return POSIX_BOTTOM_REACHED();
    435 }
    436 
    437 /*PAGE
    438  *
    439  *  _POSIX_Semaphore_Wait_support
    440  */
    441 
    442 int _POSIX_Semaphore_Wait_support(
    443   sem_t              *sem,
    444   boolean             blocking,
    445   Watchdog_Interval   timeout
    446 )
    447 {
    448   register POSIX_Semaphore_Control *the_semaphore;
    449   Objects_Locations                 location;
    450   int                               code;
    451  
    452   the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    453   switch ( location ) {
    454     case OBJECTS_ERROR:
    455       set_errno_and_return_minus_one( EINVAL );
    456     case OBJECTS_REMOTE:
    457       _Thread_Dispatch();
    458       return POSIX_MP_NOT_IMPLEMENTED();
    459       set_errno_and_return_minus_one( EINVAL );
    460     case OBJECTS_LOCAL:
    461       _CORE_semaphore_Seize(
    462         &the_semaphore->Semaphore,
    463         the_semaphore->Object.id,
    464         blocking,
    465         timeout
    466       );
    467       _Thread_Enable_dispatch();
    468       code = _Thread_Executing->Wait.return_code;
    469       switch (_Thread_Executing->Wait.return_code) {
    470         case 1:
    471           errno = EAGAIN;
    472           code = -1;
    473           break;
    474         case 3:
    475           errno = ETIMEDOUT;
    476           code = -1;
    477           break;
    478       }
    479 
    480       /*return _Thread_Executing->Wait.return_code;*/
    481       return code;
    482   }
    483   return POSIX_BOTTOM_REACHED();
    484 }
    485 
    486 /*PAGE
    487  *
    488  *  11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
    489  *
    490  *  NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
    491  */
    492 
    493 int sem_wait(
    494   sem_t *sem
    495 )
    496 {
    497   return _POSIX_Semaphore_Wait_support( sem, TRUE, THREAD_QUEUE_WAIT_FOREVER );
    498 }
    499 
    500 /*PAGE
    501  *
    502  *  11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
    503  *
    504  *  NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
    505  */
    506 
    507 int sem_trywait(
    508   sem_t *sem
    509 )
    510 {
    511   return _POSIX_Semaphore_Wait_support( sem, FALSE, THREAD_QUEUE_WAIT_FOREVER );
    512 }
    513 
    514 /*PAGE
    515  *
    516  *  11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
    517  *
    518  *  NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
    519  */
    520 
    521 int sem_timedwait(
    522   sem_t                 *sem,
    523   const struct timespec *timeout
    524 )
    525 {
    526   return _POSIX_Semaphore_Wait_support(
    527     sem,
    528     TRUE,
    529     _POSIX_Timespec_to_interval( timeout )
    530   );
    531 }
    532 
    533 /*PAGE
    534  *
    535  *  11.2.7 Unlock a Semaphore, P1003.1b-1993, p.227
    536  */
    537 
    538 void POSIX_Semaphore_MP_support(
    539   Thread_Control *the_thread,
    540   Objects_Id      id
    541 )
    542 {
    543   (void) POSIX_MP_NOT_IMPLEMENTED();
    544 }
    545  
    546 
    547 int sem_post(
    548   sem_t  *sem
    549 )
    550 {
    551   register POSIX_Semaphore_Control *the_semaphore;
    552   Objects_Locations                 location;
    553  
    554   the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    555   switch ( location ) {
    556     case OBJECTS_ERROR:
    557       set_errno_and_return_minus_one( EINVAL );
    558     case OBJECTS_REMOTE:
    559       _Thread_Dispatch();
    560       return POSIX_MP_NOT_IMPLEMENTED();
    561       set_errno_and_return_minus_one( EINVAL );
    562     case OBJECTS_LOCAL:
    563       _CORE_semaphore_Surrender(
    564         &the_semaphore->Semaphore,
    565         the_semaphore->Object.id,
    566 #if defined(RTEMS_MULTIPROCESSING)
    567         POSIX_Semaphore_MP_support
    568 #else
    569         NULL
    570 #endif
    571       );
    572       _Thread_Enable_dispatch();
    573       return 0;
    574   }
    575   return POSIX_BOTTOM_REACHED();
    576 }
    577 
    578 /*PAGE
    579  *
    580  *  11.2.8 Get the Value of a Semaphore, P1003.1b-1993, p.229
    581  */
    582 
    583 int sem_getvalue(
    584   sem_t  *sem,
    585   int    *sval
    586 )
    587 {
    588   register POSIX_Semaphore_Control *the_semaphore;
    589   Objects_Locations                 location;
    590  
    591   the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    592   switch ( location ) {
    593     case OBJECTS_ERROR:
    594       set_errno_and_return_minus_one( EINVAL );
    595     case OBJECTS_REMOTE:
    596       _Thread_Dispatch();
    597       return POSIX_MP_NOT_IMPLEMENTED();
    598       set_errno_and_return_minus_one( EINVAL );
    599     case OBJECTS_LOCAL:
    600       *sval = _CORE_semaphore_Get_count( &the_semaphore->Semaphore );
    601       _Thread_Enable_dispatch();
    602       return 0;
    603   }
    604   return POSIX_BOTTOM_REACHED();
    605 }
    606 
    607 /*PAGE
    608  *
    609  *  _POSIX_Semaphore_Name_to_id
    610  *
    611  *  XXX
    612  */
    613 
    614 int _POSIX_Semaphore_Name_to_id(
    615   const char          *name,
    616   Objects_Id          *id
    617 )
    618 {
    619   Objects_Name_to_id_errors  status;
    620 
    621   status = _Objects_Name_to_id( &_POSIX_Semaphore_Information, (char *)name, 0, id );
    622 
    623   if ( status == OBJECTS_SUCCESSFUL ) {
    624           return 0;
    625   } else {
    626           return EINVAL;
    627   }
    628 }
    629 
Note: See TracChangeset for help on using the changeset viewer.