Changeset c090db7 in rtems


Ignore:
Timestamp:
Sep 12, 2017, 6:09:16 AM (19 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
e67929c
Parents:
47b1e31
git-author:
Sebastian Huber <sebastian.huber@…> (09/12/17 06:09:16)
git-committer:
Sebastian Huber <sebastian.huber@…> (10/05/17 12:29:01)
Message:

posix: Implement self-contained POSIX semaphores

For semaphore object pointer and object validation see
POSIX_SEMAPHORE_VALIDATE_OBJECT().

Destruction or close of a busy semaphore returns an error status. The
object is not flushed.

POSIX semaphores are now available in all configurations and no longer
depend on --enable-posix.

Update #2514.
Update #3116.

Files:
1 added
2 deleted
28 edited

Legend:

Unmodified
Added
Removed
  • cpukit/posix/Makefile.am

    r47b1e31 rc090db7  
    2222include_rtems_posix_HEADERS += include/rtems/posix/posixapi.h
    2323include_rtems_posix_HEADERS += include/rtems/posix/priorityimpl.h
     24include_rtems_posix_HEADERS += include/rtems/posix/semaphore.h
     25include_rtems_posix_HEADERS += include/rtems/posix/semaphoreimpl.h
    2426include_rtems_posix_HEADERS += include/rtems/posix/spinlockimpl.h
    2527
     
    4547include_rtems_posix_HEADERS += include/rtems/posix/shm.h
    4648include_rtems_posix_HEADERS += include/rtems/posix/shmimpl.h
    47 include_rtems_posix_HEADERS += include/rtems/posix/semaphore.h
    48 include_rtems_posix_HEADERS += include/rtems/posix/semaphoreimpl.h
    4949include_rtems_posix_HEADERS += include/rtems/posix/threadsup.h
    5050include_rtems_posix_HEADERS += include/rtems/posix/timer.h
     
    187187libposix_a_SOURCES += src/pspinunlock.c
    188188
     189## SEMAPHORE_C_FILES
     190libposix_a_SOURCES += src/semdestroy.c
     191libposix_a_SOURCES += src/semgetvalue.c
     192libposix_a_SOURCES += src/seminit.c
     193libposix_a_SOURCES += src/sempost.c
     194libposix_a_SOURCES += src/semtimedwait.c
     195libposix_a_SOURCES += src/semtrywait.c
     196libposix_a_SOURCES += src/semwait.c
     197
    189198if HAS_PTHREADS
    190199libposix_a_SOURCES += src/sigpending.c \
     
    200209
    201210## SEMAPHORE_C_FILES
    202 libposix_a_SOURCES += src/semaphore.c src/semaphorecreatesupp.c \
    203     src/semaphoredeletesupp.c \
    204     src/semaphorewaitsupp.c \
    205     src/semclose.c src/semdestroy.c src/semgetvalue.c src/seminit.c \
    206     src/semopen.c src/sempost.c src/semtimedwait.c src/semtrywait.c \
    207     src/semunlink.c src/semwait.c
     211libposix_a_SOURCES += src/semaphore.c
     212libposix_a_SOURCES += src/semaphoredeletesupp.c
     213libposix_a_SOURCES += src/semclose.c
     214libposix_a_SOURCES += src/semopen.c
     215libposix_a_SOURCES += src/semunlink.c
    208216
    209217## TIME_C_FILES
  • cpukit/posix/include/rtems/posix/semaphore.h

    r47b1e31 rc090db7  
    2222#include <semaphore.h>
    2323#include <rtems/score/object.h>
    24 #include <rtems/score/coresem.h>
    2524
    2625#ifdef __cplusplus
     
    4241
    4342typedef struct {
    44    Objects_Control         Object;
    45    CORE_semaphore_Control  Semaphore;
    46    bool                    named;
    47    bool                    linked;
    48    uint32_t                open_count;
    49    /*
    50     *  sem_t is 32-bit.  If Object_Id is 16-bit, then they are not
    51     *  interchangeable.  We have to be able to return a pointer to
    52     *  a 32-bit form of the 16-bit Id.
    53     */
    54    #if defined(RTEMS_USE_16_BIT_OBJECT)
    55      sem_t                 Semaphore_id;
    56    #endif
     43   Objects_Control Object;
     44   sem_t           Semaphore;
     45   bool            linked;
     46   uint32_t        open_count;
    5747}  POSIX_Semaphore_Control;
    5848
  • cpukit/posix/include/rtems/posix/semaphoreimpl.h

    r47b1e31 rc090db7  
    2222#include <rtems/posix/semaphore.h>
    2323#include <rtems/posix/posixapi.h>
    24 #include <rtems/score/coresemimpl.h>
     24#include <rtems/score/semaphoreimpl.h>
    2525#include <rtems/seterr.h>
    2626
     
    3030
    3131/**
     32 * @brief This is a random number used to check if a semaphore object is
     33 * properly initialized.
     34 */
     35#define POSIX_SEMAPHORE_MAGIC 0x5d367fe7UL
     36
     37/**
    3238 *  This defines the information control block used to manage
    3339 *  this class of objects.
    3440 */
    3541extern Objects_Information _POSIX_Semaphore_Information;
    36 
    37 #define POSIX_SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
    3842
    3943RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *
     
    5862
    5963RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get(
    60   const sem_t          *id,
    61   Thread_queue_Context *queue_context
     64  sem_t *sem
    6265)
    6366{
    64   _Thread_queue_Context_initialize( queue_context );
    65   return (POSIX_Semaphore_Control *) _Objects_Get(
    66     (Objects_Id) *id,
    67     &queue_context->Lock_context.Lock_context,
    68     &_POSIX_Semaphore_Information
    69   );
     67  return RTEMS_CONTAINER_OF( sem, POSIX_Semaphore_Control, Semaphore );
    7068}
    7169
    72 /**
    73  *  @brief POSIX Semaphore Create Support
    74  *
    75  *  This routine supports the sem_init and sem_open routines.
    76  */
     70RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_named( const sem_t *sem )
     71{
     72  return sem->_Semaphore._Queue._name != NULL;
     73}
    7774
    78 int _POSIX_Semaphore_Create_support(
    79   const char                *name,
    80   size_t                     name_len,
    81   unsigned int               value,
    82   POSIX_Semaphore_Control  **the_sem
    83 );
     75RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_busy( const sem_t *sem )
     76{
     77  return sem->_Semaphore._Queue._heads != NULL;
     78}
     79
     80RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Initialize(
     81  sem_t        *sem,
     82  const char   *name,
     83  unsigned int  value
     84)
     85{
     86  sem->_flags = (uintptr_t) sem ^ POSIX_SEMAPHORE_MAGIC;
     87  _Semaphore_Initialize_named( &sem->_Semaphore, name, value );
     88}
     89
     90RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Destroy( sem_t *sem )
     91{
     92  sem->_flags = 0;
     93  _Semaphore_Destroy( &sem->_Semaphore );
     94}
    8495
    8596/**
     
    8899 * This routine supports the sem_close and sem_unlink routines.
    89100 */
    90 void _POSIX_Semaphore_Delete(
    91   POSIX_Semaphore_Control *the_semaphore,
    92   Thread_queue_Context    *queue_context
    93 );
     101void _POSIX_Semaphore_Delete( POSIX_Semaphore_Control *the_semaphore );
    94102
    95 /**
    96  * @brief POSIX semaphore wait support.
    97  *
    98  * This routine supports the sem_wait, sem_trywait, and sem_timedwait
    99  * services.
    100  */
    101 int _POSIX_Semaphore_Wait_support(
    102   sem_t               *sem,
    103   bool                 blocking,
    104   Watchdog_Interval    timeout
    105 );
    106  
    107103/**
    108104 *  @brief POSIX Semaphore Namespace Remove
     
    130126}
    131127
     128#define POSIX_SEMAPHORE_VALIDATE_OBJECT( sem ) \
     129  do { \
     130    if ( \
     131      ( sem ) == NULL \
     132        || ( (uintptr_t) ( sem ) ^ POSIX_SEMAPHORE_MAGIC ) != ( sem )->_flags \
     133    ) { \
     134      rtems_set_errno_and_return_minus_one( EINVAL ); \
     135    } \
     136  } while ( 0 )
     137
    132138#ifdef __cplusplus
    133139}
  • cpukit/posix/preinstall.am

    r47b1e31 rc090db7  
    4747        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h
    4848PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h
     49
     50$(PROJECT_INCLUDE)/rtems/posix/semaphore.h: include/rtems/posix/semaphore.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
     51        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
     52PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
     53
     54$(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h: include/rtems/posix/semaphoreimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
     55        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
     56PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
    4957
    5058$(PROJECT_INCLUDE)/rtems/posix/spinlockimpl.h: include/rtems/posix/spinlockimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
     
    121129PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/shmimpl.h
    122130
    123 $(PROJECT_INCLUDE)/rtems/posix/semaphore.h: include/rtems/posix/semaphore.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
    124         $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
    125 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
    126 
    127 $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h: include/rtems/posix/semaphoreimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
    128         $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
    129 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
    130 
    131131$(PROJECT_INCLUDE)/rtems/posix/threadsup.h: include/rtems/posix/threadsup.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
    132132        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
  • cpukit/posix/src/semaphore.c

    r47b1e31 rc090db7  
    1919#endif
    2020
    21 #include <stdarg.h>
    22 
    23 #include <errno.h>
    24 #include <fcntl.h>
    25 #include <pthread.h>
    26 #include <semaphore.h>
    27 #include <limits.h>
    28 
    29 #include <rtems/system.h>
     21#include <rtems/posix/semaphoreimpl.h>
    3022#include <rtems/config.h>
    3123#include <rtems/sysinit.h>
    32 #include <rtems/posix/semaphoreimpl.h>
    33 #include <rtems/seterr.h>
     24
     25#include <limits.h>
    3426
    3527Objects_Information _POSIX_Semaphore_Information;
  • cpukit/posix/src/semaphoredeletesupp.c

    r47b1e31 rc090db7  
    2121#include <rtems/posix/semaphoreimpl.h>
    2222
    23 void _POSIX_Semaphore_Delete(
    24   POSIX_Semaphore_Control *the_semaphore,
    25   Thread_queue_Context    *queue_context
    26 )
     23void _POSIX_Semaphore_Delete( POSIX_Semaphore_Control *the_semaphore )
    2724{
    2825  if ( !the_semaphore->linked && !the_semaphore->open_count ) {
    2926    _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
    30     _CORE_semaphore_Destroy(
    31       &the_semaphore->Semaphore,
    32       POSIX_SEMAPHORE_TQ_OPERATIONS,
    33       queue_context
    34     );
     27    _POSIX_Semaphore_Destroy( &the_semaphore->Semaphore );
    3528    _POSIX_Semaphore_Free( the_semaphore );
    36   } else {
    37     _CORE_semaphore_Release( &the_semaphore->Semaphore, queue_context );
    3829  }
    3930}
  • cpukit/posix/src/semclose.c

    r47b1e31 rc090db7  
    1919#endif
    2020
    21 #include <semaphore.h>
    22 
    2321#include <rtems/posix/semaphoreimpl.h>
    2422
    25 int sem_close(
    26   sem_t *sem
    27 )
     23int sem_close( sem_t *sem )
    2824{
    2925  POSIX_Semaphore_Control *the_semaphore;
    30   Thread_queue_Context     queue_context;
     26  uint32_t                 open_count;
     27
     28  POSIX_SEMAPHORE_VALIDATE_OBJECT( sem );
     29
     30  if ( !_POSIX_Semaphore_Is_named( sem ) ) {
     31    rtems_set_errno_and_return_minus_one( EINVAL );
     32  }
     33
     34  the_semaphore = _POSIX_Semaphore_Get( sem );
    3135
    3236  _Objects_Allocator_lock();
    33   the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
    3437
    35   if ( the_semaphore == NULL ) {
     38  open_count = the_semaphore->open_count;
     39
     40  if ( open_count == 0 ) {
    3641    _Objects_Allocator_unlock();
    3742    rtems_set_errno_and_return_minus_one( EINVAL );
    3843  }
    3944
    40   _CORE_semaphore_Acquire_critical(
    41     &the_semaphore->Semaphore,
    42     &queue_context
    43   );
    44   the_semaphore->open_count -= 1;
    45   _POSIX_Semaphore_Delete( the_semaphore, &queue_context );
     45  if ( open_count == 1 && _POSIX_Semaphore_Is_busy( sem ) ) {
     46    _Objects_Allocator_unlock();
     47    rtems_set_errno_and_return_minus_one( EBUSY );
     48  }
    4649
     50  the_semaphore->open_count = open_count - 1;
     51  _POSIX_Semaphore_Delete( the_semaphore );
    4752  _Objects_Allocator_unlock();
    4853  return 0;
  • cpukit/posix/src/semdestroy.c

    r47b1e31 rc090db7  
    1919#endif
    2020
    21 #include <semaphore.h>
    22 
    2321#include <rtems/posix/semaphoreimpl.h>
    2422
    25 int sem_destroy(
    26   sem_t *sem
    27 )
     23int sem_destroy( sem_t *sem )
    2824{
    29   POSIX_Semaphore_Control *the_semaphore;
    30   Thread_queue_Context     queue_context;
     25  POSIX_SEMAPHORE_VALIDATE_OBJECT( sem );
    3126
    32   _Objects_Allocator_lock();
    33   the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
    34 
    35   if ( the_semaphore == NULL ) {
    36     _Objects_Allocator_unlock();
     27  if ( _POSIX_Semaphore_Is_named( sem ) ) {
    3728    rtems_set_errno_and_return_minus_one( EINVAL );
    3829  }
    3930
    40   _CORE_semaphore_Acquire_critical(
    41     &the_semaphore->Semaphore,
    42     &queue_context
    43   );
    44 
    45   if ( the_semaphore->named ) {
    46     /* Undefined operation on a named semaphore */
    47     _CORE_semaphore_Release( &the_semaphore->Semaphore, &queue_context );
    48     _Objects_Allocator_unlock();
    49     rtems_set_errno_and_return_minus_one( EINVAL );
     31  if ( _POSIX_Semaphore_Is_busy( sem ) ) {
     32    rtems_set_errno_and_return_minus_one( EBUSY );
    5033  }
    5134
    52   _POSIX_Semaphore_Delete( the_semaphore, &queue_context );
    53 
    54   _Objects_Allocator_unlock();
     35  _POSIX_Semaphore_Destroy( sem );
    5536  return 0;
    5637}
  • cpukit/posix/src/semgetvalue.c

    r47b1e31 rc090db7  
    1919#endif
    2020
    21 #include <semaphore.h>
    22 
    2321#include <rtems/posix/semaphoreimpl.h>
    2422
    2523int sem_getvalue(
    26   sem_t  *__restrict sem,
     24  sem_t  *__restrict _sem,
    2725  int    *__restrict sval
    2826)
    2927{
    30   POSIX_Semaphore_Control *the_semaphore;
    31   Thread_queue_Context     queue_context;
     28  Sem_Control          *sem;
     29  ISR_Level             level;
     30  Thread_queue_Context  queue_context;
    3231
    33   the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
     32  POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
    3433
    35   if ( the_semaphore == NULL ) {
    36     rtems_set_errno_and_return_minus_one( EINVAL );
    37   }
    38 
    39   _CORE_semaphore_Acquire_critical(
    40     &the_semaphore->Semaphore,
    41     &queue_context
    42   );
    43 
    44   *sval = _CORE_semaphore_Get_count( &the_semaphore->Semaphore );
    45 
    46   _CORE_semaphore_Release( &the_semaphore->Semaphore, &queue_context );
     34  sem = _Sem_Get( &_sem->_Semaphore );
     35  _Thread_queue_Context_initialize( &queue_context );
     36  _Thread_queue_Context_ISR_disable( &queue_context, level );
     37  _Sem_Queue_acquire_critical( sem, &queue_context );
     38  *sval = (int) sem->count;
     39  _Sem_Queue_release( sem, level, &queue_context );
    4740  return 0;
    4841}
  • cpukit/posix/src/seminit.c

    r47b1e31 rc090db7  
    1919#endif
    2020
    21 #include <stdarg.h>
     21#include <rtems/posix/semaphoreimpl.h>
    2222
    23 #include <errno.h>
    24 #include <fcntl.h>
    25 #include <pthread.h>
    26 #include <semaphore.h>
    2723#include <limits.h>
    2824
    29 #include <rtems/system.h>
    30 #include <rtems/posix/semaphoreimpl.h>
    31 #include <rtems/seterr.h>
     25RTEMS_STATIC_ASSERT(NULL == SEM_FAILED, sem_failed);
    3226
    3327/*
     
    4135)
    4236{
    43   int                        status;
    44   POSIX_Semaphore_Control   *the_semaphore;
    45 
    4637  if ( sem == NULL ) {
    4738    rtems_set_errno_and_return_minus_one( EINVAL );
     
    5243  }
    5344
    54   _Objects_Allocator_lock();
    55   status = _POSIX_Semaphore_Create_support(
    56     NULL,
    57     0,
    58     value,
    59     &the_semaphore
    60   );
    61   _Objects_Allocator_unlock();
    62 
    63   if ( status != -1 )
    64     *sem = the_semaphore->Object.id;
    65 
    66   return status;
     45  _POSIX_Semaphore_Initialize( sem, NULL, value );
     46  return 0;
    6747}
  • cpukit/posix/src/semopen.c

    r47b1e31 rc090db7  
    1919#endif
    2020
     21#include <rtems/posix/semaphoreimpl.h>
     22#include <rtems/score/wkspace.h>
     23
    2124#include <stdarg.h>
    22 
    23 #include <errno.h>
    2425#include <fcntl.h>
    25 #include <pthread.h>
    26 #include <semaphore.h>
    2726#include <limits.h>
    2827
    29 #include <rtems/system.h>
    30 #include <rtems/posix/semaphoreimpl.h>
    31 #include <rtems/seterr.h>
     28static sem_t *_POSIX_Semaphore_Create_support(
     29  const char   *name_arg,
     30  size_t        name_len,
     31  unsigned int  value
     32)
     33{
     34  POSIX_Semaphore_Control *the_semaphore;
     35  char                    *name;
     36
     37  if ( value > SEM_VALUE_MAX ) {
     38    rtems_set_errno_and_return_value( EINVAL, SEM_FAILED );
     39  }
     40
     41  /*
     42   * Make a copy of the user's string for name just in case it was
     43   * dynamically constructed.
     44   */
     45  name = _Workspace_String_duplicate( name_arg, name_len );
     46  if ( name == NULL ) {
     47    rtems_set_errno_and_return_value( ENOMEM, SEM_FAILED );
     48  }
     49
     50  the_semaphore = _POSIX_Semaphore_Allocate_unprotected();
     51  if ( the_semaphore == NULL ) {
     52    _Workspace_Free( name );
     53    rtems_set_errno_and_return_value( ENOSPC, SEM_FAILED );
     54  }
     55
     56  the_semaphore->open_count = 1;
     57  the_semaphore->linked = true;
     58
     59  /*
     60   *  POSIX does not appear to specify what the discipline for
     61   *  blocking tasks on this semaphore should be.  It could somehow
     62   *  be derived from the current scheduling policy.  One
     63   *  thing is certain, no matter what we decide, it won't be
     64   *  the same as  all other POSIX implementations. :)
     65   */
     66  _POSIX_Semaphore_Initialize( &the_semaphore->Semaphore, name, value );
     67
     68  /*
     69   *  Make the semaphore available for use.
     70   */
     71  _Objects_Open_string(
     72    &_POSIX_Semaphore_Information,
     73    &the_semaphore->Object,
     74    name
     75  );
     76
     77  return &the_semaphore->Semaphore;
     78}
    3279
    3380/*
     
    60107  va_list                    arg;
    61108  unsigned int               value = 0;
    62   int                        status;
    63109  POSIX_Semaphore_Control   *the_semaphore;
    64110  size_t                     name_len;
    65111  Objects_Get_by_name_error  error;
     112  sem_t                     *sem;
    66113
    67114  if ( oflag & O_CREAT ) {
     
    109156    the_semaphore->open_count += 1;
    110157    _Objects_Allocator_unlock();
    111     goto return_id;
     158    return &the_semaphore->Semaphore;
    112159  }
    113160
     
    117164   */
    118165
    119   status =_POSIX_Semaphore_Create_support(
     166  sem = _POSIX_Semaphore_Create_support(
    120167    name,
    121168    name_len,
    122     value,
    123     &the_semaphore
     169    value
    124170  );
    125171
    126   /*
    127    * errno was set by Create_support, so don't set it again.
    128    */
    129 
    130172  _Objects_Allocator_unlock();
    131 
    132   if ( status != 0 )
    133     return SEM_FAILED;
    134 
    135 return_id:
    136   #if defined(RTEMS_USE_16_BIT_OBJECT)
    137     the_semaphore->Semaphore_id = the_semaphore->Object.id;
    138     return &the_semaphore->Semaphore_id;
    139   #else
    140     return &the_semaphore->Object.id;
    141   #endif
     173  return sem;
    142174}
  • cpukit/posix/src/sempost.c

    r47b1e31 rc090db7  
    1919#endif
    2020
    21 #include <semaphore.h>
     21#include <rtems/posix/semaphoreimpl.h>
     22
    2223#include <limits.h>
    2324
    24 #include <rtems/posix/semaphoreimpl.h>
    25 #include <rtems/posix/posixapi.h>
     25int sem_post( sem_t *_sem )
     26{
     27  Sem_Control          *sem;
     28  ISR_Level             level;
     29  Thread_queue_Context  queue_context;
     30  Thread_queue_Heads   *heads;
     31  unsigned int          count;
    2632
    27 int sem_post(
    28   sem_t  *sem
    29 )
    30 {
    31   POSIX_Semaphore_Control *the_semaphore;
    32   Thread_queue_Context     queue_context;
    33   Status_Control           status;
     33  POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
    3434
    35   the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
     35  sem = _Sem_Get( &_sem->_Semaphore );
     36  _Thread_queue_Context_initialize( &queue_context );
     37  _Thread_queue_Context_ISR_disable( &queue_context, level );
     38  _Sem_Queue_acquire_critical( sem, &queue_context );
    3639
    37   if ( the_semaphore == NULL ) {
    38     rtems_set_errno_and_return_minus_one( EINVAL );
     40  heads = sem->Queue.Queue.heads;
     41  count = sem->count;
     42
     43  if ( __predict_true( heads == NULL && count < SEM_VALUE_MAX ) ) {
     44    sem->count = count + 1;
     45    _Sem_Queue_release( sem, level, &queue_context );
     46    return 0;
    3947  }
    4048
    41   status = _CORE_semaphore_Surrender(
    42     &the_semaphore->Semaphore,
    43     POSIX_SEMAPHORE_TQ_OPERATIONS,
    44     SEM_VALUE_MAX,
    45     &queue_context
    46   );
    47   return _POSIX_Zero_or_minus_one_plus_errno( status );
     49  if ( __predict_true( heads != NULL ) ) {
     50    const Thread_queue_Operations *operations;
     51    Thread_Control *first;
     52
     53    _Thread_queue_Context_set_ISR_level( &queue_context, level );
     54    operations = SEMAPHORE_TQ_OPERATIONS;
     55    first = ( *operations->first )( heads );
     56
     57    _Thread_queue_Extract_critical(
     58      &sem->Queue.Queue,
     59      operations,
     60      first,
     61      &queue_context
     62    );
     63    return 0;
     64  }
     65
     66  _Sem_Queue_release( sem, level, &queue_context );
     67  rtems_set_errno_and_return_minus_one( EOVERFLOW );
    4868}
  • cpukit/posix/src/semtimedwait.c

    r47b1e31 rc090db7  
    1919#endif
    2020
    21 #include <stdarg.h>
    22 
    23 #include <errno.h>
    24 #include <fcntl.h>
    25 #include <pthread.h>
    26 #include <semaphore.h>
    27 #include <limits.h>
    28 
    29 #include <rtems/system.h>
     21#include <rtems/posix/semaphoreimpl.h>
    3022#include <rtems/score/todimpl.h>
    31 #include <rtems/posix/semaphoreimpl.h>
    32 #include <rtems/seterr.h>
    3323
    3424/*
     
    3929
    4030int sem_timedwait(
    41   sem_t                 *__restrict sem,
     31  sem_t                 *__restrict _sem,
    4232  const struct timespec *__restrict abstime
    4333)
    4434{
    45   Watchdog_Interval                            ticks;
    46   bool                                         do_wait = true;
    47   TOD_Absolute_timeout_conversion_results  status;
    48   int                                          lock_status;
     35  Sem_Control          *sem;
     36  Thread_queue_Context  queue_context;
     37  ISR_Level             level;
     38  Thread_Control       *executing;
     39  unsigned int          count;
    4940
    50   /*
    51    *  POSIX requires that blocking calls with timeouts that take
    52    *  an absolute timeout must ignore issues with the absolute
    53    *  time provided if the operation would otherwise succeed.
    54    *  So we check the abstime provided, and hold on to whether it
    55    *  is valid or not.  If it isn't correct and in the future,
    56    *  then we do a polling operation and convert the UNSATISFIED
    57    *  status into the appropriate error.
    58    *
    59    *  If the status is TOD_ABSOLUTE_TIMEOUT_INVALID,
    60    *  TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
    61    *  then we should not wait.
    62    */
    63   status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
    64   if ( status != TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE )
    65     do_wait = false;
     41  POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
    6642
    67   lock_status = _POSIX_Semaphore_Wait_support( sem, do_wait, ticks );
     43  sem = _Sem_Get( &_sem->_Semaphore );
     44  _Thread_queue_Context_initialize( &queue_context );
     45  _Thread_queue_Context_ISR_disable( &queue_context, level );
     46  executing = _Sem_Queue_acquire_critical( sem, &queue_context );
    6847
    69   /*
    70    *  This service only gives us the option to block.  We used a polling
    71    *  attempt to obtain if the abstime was not in the future.  If we did
    72    *  not obtain the semaphore, then not look at the status immediately,
    73    *  make sure the right reason is returned.
    74    */
    75   if ( !do_wait && (lock_status == EBUSY) ) {
    76     if ( lock_status == TOD_ABSOLUTE_TIMEOUT_INVALID )
    77       rtems_set_errno_and_return_minus_one( EINVAL );
    78     if ( lock_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST ||
    79          lock_status == TOD_ABSOLUTE_TIMEOUT_IS_NOW )
    80       rtems_set_errno_and_return_minus_one( ETIMEDOUT );
     48  count = sem->count;
     49  if ( __predict_true( count > 0 ) ) {
     50    sem->count = count - 1;
     51    _Sem_Queue_release( sem, level, &queue_context );
     52    return 0;
     53  } else {
     54    Watchdog_Interval ticks;
     55    Status_Control    status;
     56
     57    switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) {
     58      case TOD_ABSOLUTE_TIMEOUT_INVALID:
     59        _Sem_Queue_release( sem, level, &queue_context );
     60        rtems_set_errno_and_return_minus_one( EINVAL );
     61        break;
     62      case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST:
     63      case TOD_ABSOLUTE_TIMEOUT_IS_NOW:
     64        _Sem_Queue_release( sem, level, &queue_context );
     65        rtems_set_errno_and_return_minus_one( ETIMEDOUT );
     66        break;
     67      default:
     68        break;
     69    }
     70
     71    _Thread_queue_Context_set_thread_state(
     72      &queue_context,
     73      STATES_WAITING_FOR_SEMAPHORE
     74    );
     75    _Thread_queue_Context_set_do_nothing_enqueue_callout( &queue_context );
     76    _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
     77    _Thread_queue_Context_set_ISR_level( &queue_context, level );
     78    _Thread_queue_Enqueue(
     79      &sem->Queue.Queue,
     80      SEMAPHORE_TQ_OPERATIONS,
     81      executing,
     82      &queue_context
     83    );
     84    status = _Thread_Wait_get_status( executing );
     85    return _POSIX_Zero_or_minus_one_plus_errno( status );
    8186  }
    82 
    83   return lock_status;
    8487}
  • cpukit/posix/src/semtrywait.c

    r47b1e31 rc090db7  
    1919#endif
    2020
    21 #include <stdarg.h>
     21#include <rtems/posix/semaphoreimpl.h>
    2222
    23 #include <errno.h>
    24 #include <fcntl.h>
    25 #include <pthread.h>
    26 #include <semaphore.h>
    27 #include <limits.h>
     23int sem_trywait( sem_t *_sem )
     24{
     25  Sem_Control          *sem;
     26  Thread_queue_Context  queue_context;
     27  ISR_Level             level;
     28  unsigned int          count;
    2829
    29 #include <rtems/system.h>
    30 #include <rtems/posix/semaphoreimpl.h>
    31 #include <rtems/seterr.h>
     30  POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );
    3231
    33 int sem_trywait(
    34   sem_t *sem
    35 )
    36 {
    37   return _POSIX_Semaphore_Wait_support(sem, false, WATCHDOG_NO_TIMEOUT);
     32  sem = _Sem_Get( &_sem->_Semaphore );
     33  _Thread_queue_Context_initialize( &queue_context );
     34  _Thread_queue_Context_ISR_disable( &queue_context, level );
     35  _Sem_Queue_acquire_critical( sem, &queue_context );
     36
     37  count = sem->count;
     38  if ( __predict_true( count > 0 ) ) {
     39    sem->count = count - 1;
     40    _Sem_Queue_release( sem, level, &queue_context );
     41    return 0;
     42  } else {
     43    _Sem_Queue_release( sem, level, &queue_context );
     44    rtems_set_errno_and_return_minus_one( EAGAIN );
     45  }
    3846}
  • cpukit/posix/src/semunlink.c

    r47b1e31 rc090db7  
    1919#endif
    2020
    21 #include <semaphore.h>
    22 
    2321#include <rtems/posix/semaphoreimpl.h>
    2422
    25 int sem_unlink(
    26   const char *name
    27 )
     23int sem_unlink( const char *name )
    2824{
    2925  POSIX_Semaphore_Control   *the_semaphore;
    3026  Objects_Get_by_name_error  error;
    31   Thread_queue_Context       queue_context;
    3227
    3328  _Objects_Allocator_lock();
     
    4035
    4136  _POSIX_Semaphore_Namespace_remove( the_semaphore );
    42 
    43   _ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context );
    44   _CORE_semaphore_Acquire_critical( &the_semaphore->Semaphore, &queue_context );
    4537  the_semaphore->linked = false;
    46   _POSIX_Semaphore_Delete( the_semaphore, &queue_context );
    47 
     38  _POSIX_Semaphore_Delete( the_semaphore );
    4839  _Objects_Allocator_unlock();
    4940  return 0;
  • cpukit/posix/src/semwait.c

    r47b1e31 rc090db7  
    1919#endif
    2020
    21 #include <stdarg.h>
     21#include <rtems/posix/semaphoreimpl.h>
    2222
    23 #include <errno.h>
    24 #include <fcntl.h>
    25 #include <pthread.h>
    26 #include <semaphore.h>
    27 #include <limits.h>
    28 
    29 #include <rtems/system.h>
    30 #include <rtems/posix/semaphoreimpl.h>
    31 #include <rtems/seterr.h>
    32 
    33 int sem_wait(
    34   sem_t *sem
    35 )
     23int sem_wait( sem_t *sem )
    3624{
    37   return _POSIX_Semaphore_Wait_support( sem, true, WATCHDOG_NO_TIMEOUT );
     25  POSIX_SEMAPHORE_VALIDATE_OBJECT( sem );
     26  _Semaphore_Wait( &sem->_Semaphore );
     27  return 0;
    3828}
  • cpukit/sapi/src/posixapi.c

    r47b1e31 rc090db7  
    2121
    2222#include <rtems/posix/posixapi.h>
     23#include <rtems/posix/semaphoreimpl.h>
     24#include <rtems/score/heap.h>
     25
     26#ifdef HEAP_PROTECTION
     27RTEMS_STATIC_ASSERT(
     28  POSIX_SEMAPHORE_MAGIC != HEAP_BEGIN_PROTECTOR_0,
     29  POSIX_SEMAPHORE_MAGIC_0
     30);
     31RTEMS_STATIC_ASSERT(
     32  POSIX_SEMAPHORE_MAGIC != HEAP_BEGIN_PROTECTOR_1,
     33  POSIX_SEMAPHORE_MAGIC_1
     34);
     35RTEMS_STATIC_ASSERT(
     36  POSIX_SEMAPHORE_MAGIC != HEAP_END_PROTECTOR_0,
     37  POSIX_SEMAPHORE_MAGIC_2
     38);
     39RTEMS_STATIC_ASSERT(
     40  POSIX_SEMAPHORE_MAGIC != HEAP_END_PROTECTOR_1,
     41  POSIX_SEMAPHORE_MAGIC_3
     42);
     43RTEMS_STATIC_ASSERT(
     44  POSIX_SEMAPHORE_MAGIC != HEAP_FREE_PATTERN,
     45  POSIX_SEMAPHORE_MAGIC_4
     46);
     47#endif
    2348
    2449void _POSIX_Fatal_error( POSIX_Fatal_domain domain, int eno )
  • cpukit/score/Makefile.am

    r47b1e31 rc090db7  
    8181include_rtems_score_HEADERS += include/rtems/score/schedulersmp.h
    8282include_rtems_score_HEADERS += include/rtems/score/schedulersmpimpl.h
     83include_rtems_score_HEADERS += include/rtems/score/semaphoreimpl.h
    8384include_rtems_score_HEADERS += include/rtems/score/smp.h
    8485include_rtems_score_HEADERS += include/rtems/score/smpbarrier.h
  • cpukit/score/preinstall.am

    r47b1e31 rc090db7  
    288288        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulersmpimpl.h
    289289PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulersmpimpl.h
     290
     291$(PROJECT_INCLUDE)/rtems/score/semaphoreimpl.h: include/rtems/score/semaphoreimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
     292        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/semaphoreimpl.h
     293PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/semaphoreimpl.h
    290294
    291295$(PROJECT_INCLUDE)/rtems/score/smp.h: include/rtems/score/smp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
  • cpukit/score/src/semaphore.c

    r47b1e31 rc090db7  
    1717#endif
    1818
    19 #include <sys/lock.h>
     19#include <rtems/score/semaphoreimpl.h>
     20#include <rtems/score/statesimpl.h>
    2021
    2122#include <limits.h>
    2223
    23 #include <rtems/score/assert.h>
    24 #include <rtems/score/threadimpl.h>
    25 #include <rtems/score/threadqimpl.h>
    26 
    27 #define SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_priority
    28 
    29 typedef struct {
    30   Thread_queue_Syslock_queue Queue;
    31   unsigned int count;
    32 } Semaphore_Control;
    33 
    3424RTEMS_STATIC_ASSERT(
    35   offsetof( Semaphore_Control, Queue )
     25  offsetof( Sem_Control, Queue )
    3626    == offsetof( struct _Semaphore_Control, _Queue ),
    3727  SEMAPHORE_CONTROL_QUEUE
     
    3929
    4030RTEMS_STATIC_ASSERT(
    41   offsetof( Semaphore_Control, count )
     31  offsetof( Sem_Control, count )
    4232    == offsetof( struct _Semaphore_Control, _count ),
    4333  SEMAPHORE_CONTROL_COUNT
     
    4535
    4636RTEMS_STATIC_ASSERT(
    47   sizeof( Semaphore_Control ) == sizeof( struct _Semaphore_Control ),
     37  sizeof( Sem_Control ) == sizeof( struct _Semaphore_Control ),
    4838  SEMAPHORE_CONTROL_SIZE
    4939);
    5040
    51 static Semaphore_Control *_Semaphore_Get(
    52   struct _Semaphore_Control *_sem
    53 )
    54 {
    55   return (Semaphore_Control *) _sem;
    56 }
    57 
    58 static Thread_Control *_Semaphore_Queue_acquire_critical(
    59   Semaphore_Control    *sem,
    60   Thread_queue_Context *queue_context
    61 )
    62 {
    63   Thread_Control *executing;
    64 
    65   executing = _Thread_Executing;
    66   _Thread_queue_Queue_acquire_critical(
    67     &sem->Queue.Queue,
    68     &executing->Potpourri_stats,
    69     &queue_context->Lock_context.Lock_context
    70   );
    71 
    72   return executing;
    73 }
    74 
    75 static void _Semaphore_Queue_release(
    76   Semaphore_Control    *sem,
    77   ISR_Level             level,
    78   Thread_queue_Context *queue_context
    79 )
    80 {
    81   _Thread_queue_Queue_release_critical(
    82     &sem->Queue.Queue,
    83     &queue_context->Lock_context.Lock_context
    84   );
    85   _ISR_Local_enable( level );
    86 }
    87 
    8841void _Semaphore_Wait( struct _Semaphore_Control *_sem )
    8942{
    90   Semaphore_Control    *sem ;
     43  Sem_Control          *sem;
    9144  ISR_Level             level;
    9245  Thread_queue_Context  queue_context;
     
    9447  unsigned int          count;
    9548
    96   sem = _Semaphore_Get( _sem );
     49  sem = _Sem_Get( _sem );
    9750  _Thread_queue_Context_initialize( &queue_context );
    9851  _Thread_queue_Context_ISR_disable( &queue_context, level );
    99   executing = _Semaphore_Queue_acquire_critical( sem, &queue_context );
     52  executing = _Sem_Queue_acquire_critical( sem, &queue_context );
    10053
    10154  count = sem->count;
    10255  if ( __predict_true( count > 0 ) ) {
    10356    sem->count = count - 1;
    104     _Semaphore_Queue_release( sem, level, &queue_context );
     57    _Sem_Queue_release( sem, level, &queue_context );
    10558  } else {
    10659    _Thread_queue_Context_set_thread_state(
     
    12275void _Semaphore_Post( struct _Semaphore_Control *_sem )
    12376{
    124   Semaphore_Control    *sem;
     77  Sem_Control          *sem;
    12578  ISR_Level             level;
    12679  Thread_queue_Context  queue_context;
    12780  Thread_queue_Heads   *heads;
    12881
    129   sem = _Semaphore_Get( _sem );
     82  sem = _Sem_Get( _sem );
    13083  _Thread_queue_Context_initialize( &queue_context );
    13184  _Thread_queue_Context_ISR_disable( &queue_context, level );
    132   _Semaphore_Queue_acquire_critical( sem, &queue_context );
     85  _Sem_Queue_acquire_critical( sem, &queue_context );
    13386
    13487  heads = sem->Queue.Queue.heads;
     
    13689    _Assert( sem->count < UINT_MAX );
    13790    ++sem->count;
    138     _Semaphore_Queue_release( sem, level, &queue_context );
     91    _Sem_Queue_release( sem, level, &queue_context );
    13992  } else {
    14093    const Thread_queue_Operations *operations;
  • testsuites/psxtests/psxcancel/init.c

    r47b1e31 rc090db7  
    264264
    265265#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
    266 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2
    267266
    268267#define CONFIGURE_POSIX_INIT_THREAD_TABLE
  • testsuites/psxtests/psxeintr_join/init.c

    r47b1e31 rc090db7  
    131131
    132132#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
    133 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1
    134133
    135134#define CONFIGURE_INIT
  • testsuites/psxtests/psxsem01/init.c

    r47b1e31 rc090db7  
    3939  rtems_test_assert( rv == 0 );
    4040
    41   errno = 0;
    4241  rv = sem_wait( sem );
    43   rtems_test_assert( rv == -1 );
    44   rtems_test_assert( errno == EINVAL );
     42  rtems_test_assert( rv == 0 );
    4543
    4644  return NULL;
     
    7169  rtems_test_assert( val == 0 );
    7270
     71  errno = 0;
    7372  rv = sem_destroy( &sem );
     73  rtems_test_assert( rv == -1 );
     74  rtems_test_assert( errno == EBUSY );
     75
     76  rv = sem_post( &sem );
    7477  rtems_test_assert( rv == 0 );
    7578
    7679  eno = pthread_join( th, NULL );
    7780  rtems_test_assert( eno == 0 );
     81
     82  rv = sem_destroy( &sem );
     83  rtems_test_assert( rv == 0 );
     84}
     85
     86static void test_named_sem_wait_during_delete(void)
     87{
     88  sem_t     *sem;
     89  sem_t     *sem2;
     90  int        rv;
     91  pthread_t  th;
     92  int        eno;
     93  int        val;
     94
     95  sem = sem_open( "sem", O_CREAT | O_EXCL, 0777, 1 );
     96  rtems_test_assert( sem != SEM_FAILED );
     97
     98  sem2 = sem_open( "sem", 0 );
     99  rtems_test_assert( sem2 != SEM_FAILED );
     100  rtems_test_assert( sem == sem2 );
     101
     102  eno = pthread_create( &th, NULL, sem_wait_task, sem );
     103  rtems_test_assert( eno == 0 );
     104
     105  rv = sem_getvalue( sem, &val );
     106  rtems_test_assert( rv == 0 );
     107  rtems_test_assert( val == 1 );
     108
     109  sched_yield();
     110
     111  rv = sem_getvalue( sem, &val );
     112  rtems_test_assert( rv == 0 );
     113  rtems_test_assert( val == 0 );
     114
     115  rv = sem_close( sem2 );
     116  rtems_test_assert( rv == 0 );
     117
     118  errno = 0;
     119  rv = sem_close( sem );
     120  rtems_test_assert( rv == -1 );
     121  rtems_test_assert( errno == EBUSY );
     122
     123  rv = sem_post( sem );
     124  rtems_test_assert( rv == 0 );
     125
     126  eno = pthread_join( th, NULL );
     127  rtems_test_assert( eno == 0 );
     128
     129  rv = sem_close( sem );
     130  rtems_test_assert( rv == 0 );
     131
     132  rv = sem_unlink( "sem" );
     133  rtems_test_assert( rv == 0 );
    78134}
    79135
     
    112168static void test_sem_init_too_large_inital_value(void)
    113169{
     170  sem_t  sem;
     171  sem_t *sem2;
     172  int    rv;
     173
     174  errno = 0;
     175  rv = sem_init( &sem, 0, (unsigned int) SEM_VALUE_MAX + 1 );
     176  rtems_test_assert( rv == -1 );
     177  rtems_test_assert( errno == EINVAL );
     178
     179  errno = 0;
     180  sem2 = sem_open(
     181    "sem",
     182    O_CREAT | O_EXCL,
     183    0777,
     184    (unsigned int) SEM_VALUE_MAX + 1
     185  );
     186  rtems_test_assert( sem2 == SEM_FAILED );
     187  rtems_test_assert( errno == EINVAL );
     188}
     189
     190static void test_sem_null(void)
     191{
     192  int rv;
     193  int val;
     194  struct timespec to;
     195
     196  rtems_test_assert( NULL == SEM_FAILED );
     197
     198  errno = 0;
     199  rv = sem_init( NULL, 0, 0 );
     200  rtems_test_assert( rv == -1 );
     201  rtems_test_assert( errno == EINVAL );
     202
     203  errno = 0;
     204  rv = sem_wait( NULL );
     205  rtems_test_assert( rv == -1 );
     206  rtems_test_assert( errno == EINVAL );
     207
     208  errno = 0;
     209  rv = sem_post( NULL );
     210  rtems_test_assert( rv == -1 );
     211  rtems_test_assert( errno == EINVAL );
     212
     213  errno = 0;
     214  rv = sem_wait( NULL );
     215  rtems_test_assert( rv == -1 );
     216  rtems_test_assert( errno == EINVAL );
     217
     218  errno = 0;
     219  rv = sem_trywait( NULL );
     220  rtems_test_assert( rv == -1 );
     221  rtems_test_assert( errno == EINVAL );
     222
     223  to.tv_sec = 1;
     224  to.tv_nsec = 1;
     225  errno = 0;
     226  rv = sem_timedwait( NULL, &to );
     227  rtems_test_assert( rv == -1 );
     228  rtems_test_assert( errno == EINVAL );
     229
     230  errno = 0;
     231  rv = sem_getvalue( NULL, &val );
     232  rtems_test_assert( rv == -1 );
     233  rtems_test_assert( errno == EINVAL );
     234
     235  errno = 0;
     236  rv = sem_destroy( NULL );
     237  rtems_test_assert( rv == -1 );
     238  rtems_test_assert( errno == EINVAL );
     239
     240  errno = 0;
     241  rv = sem_close( NULL );
     242  rtems_test_assert( rv == -1 );
     243  rtems_test_assert( errno == EINVAL );
     244}
     245
     246static void test_sem_not_initialized(void)
     247{
    114248  sem_t sem;
     249  int rv;
     250  int val;
     251  struct timespec to;
     252
     253  memset( &sem, 0xff, sizeof( sem ) );
     254
     255  errno = 0;
     256  rv = sem_wait( &sem );
     257  rtems_test_assert( rv == -1 );
     258  rtems_test_assert( errno == EINVAL );
     259
     260  errno = 0;
     261  rv = sem_post( &sem );
     262  rtems_test_assert( rv == -1 );
     263  rtems_test_assert( errno == EINVAL );
     264
     265  errno = 0;
     266  rv = sem_wait( &sem );
     267  rtems_test_assert( rv == -1 );
     268  rtems_test_assert( errno == EINVAL );
     269
     270  errno = 0;
     271  rv = sem_trywait( &sem );
     272  rtems_test_assert( rv == -1 );
     273  rtems_test_assert( errno == EINVAL );
     274
     275  to.tv_sec = 1;
     276  to.tv_nsec = 1;
     277  errno = 0;
     278  rv = sem_timedwait( &sem, &to );
     279  rtems_test_assert( rv == -1 );
     280  rtems_test_assert( errno == EINVAL );
     281
     282  errno = 0;
     283  rv = sem_getvalue( &sem, &val );
     284  rtems_test_assert( rv == -1 );
     285  rtems_test_assert( errno == EINVAL );
     286
     287  errno = 0;
     288  rv = sem_destroy( &sem );
     289  rtems_test_assert( rv == -1 );
     290  rtems_test_assert( errno == EINVAL );
     291
     292  errno = 0;
     293  rv = sem_close( &sem );
     294  rtems_test_assert( rv == -1 );
     295  rtems_test_assert( errno == EINVAL );
     296}
     297
     298static void test_sem_invalid_copy(void)
     299{
     300  sem_t sem;
     301  sem_t sem2;
    115302  int   rv;
    116 
    117   errno = 0;
    118   rv = sem_init( &sem, 0, (unsigned int) SEM_VALUE_MAX + 1 );
     303  int   val;
     304
     305  rv = sem_init( &sem, 0, 0 );
     306  rtems_test_assert( rv == 0 );
     307
     308  val = 1;
     309  rv = sem_getvalue( &sem, &val );
     310  rtems_test_assert( rv == 0 );
     311  rtems_test_assert( val == 0 );
     312
     313  memcpy( &sem2, &sem, sizeof( sem2 ) );
     314
     315  errno = 0;
     316  rv = sem_getvalue( &sem2, &val );
     317  rtems_test_assert( rv == -1 );
     318  rtems_test_assert( errno == EINVAL );
     319
     320  rv = sem_destroy( &sem );
     321  rtems_test_assert( rv == 0 );
     322
     323  errno = 0;
     324  rv = sem_getvalue( &sem, &val );
    119325  rtems_test_assert( rv == -1 );
    120326  rtems_test_assert( errno == EINVAL );
     
    156362    fatal_posix_service_status( status, 0, failure_msg);
    157363  }
    158   puts( "Init: sem_init - UNSUCCESSFUL (ENOSPC)" );
     364
     365  puts( "Init: sem_init - SUCCESSFUL" );
    159366  status = sem_init(&sem2, 0, 1);
    160   fatal_posix_service_status( status, -1, "sem_init error return status");
    161   fatal_posix_service_status( errno, ENOSPC, "sem_init errorno ENOSPC" );
     367  fatal_posix_service_status( status, 0, "sem_init");
     368
     369  puts( "Init: sem_destroy - SUCCESSFUL" );
     370  status = sem_destroy(&sem2);
     371  fatal_posix_service_status( status, 0, "sem_destroy");
    162372
    163373  puts( "Init: sem_getvalue - SUCCESSFUL ");
     
    169379  }
    170380  puts( "Init: sem_getvalue - UNSUCCESSFUL ");
    171   sem2 = 0;
    172   status = sem_getvalue(&sem2, &value);
     381  status = sem_getvalue(SEM_FAILED, &value);
    173382  fatal_posix_service_status( status, -1, "sem_getvalue error return status");
    174383  fatal_posix_service_status( errno, EINVAL, "sem_getvalue errno EINVAL");
     
    179388
    180389  puts( "Init: sem_destroy - UNSUCCESSFUL (EINVAL)" );
    181   status = sem_destroy(&sem2);
     390  status = sem_destroy(SEM_FAILED);
    182391  fatal_posix_service_status( status, -1, "sem_destroy error return status");
    183392  fatal_posix_service_status( errno, EINVAL, "sem_destroy errno EINVAL");
     
    189398
    190399  puts( "Init: sem_wait - UNSUCCESSFUL (EINVAL)" );
    191   status = sem_wait(&sem2);
     400  status = sem_wait(SEM_FAILED);
    192401  fatal_posix_service_status( status, -1, "sem_wait error return status");
    193402  fatal_posix_service_status( errno, EINVAL, "sem_wait errno EINVAL");
     
    215424
    216425  puts( "Init: sem_trywait - UNSUCCESSFUL (EINVAL)" );
    217   status = sem_trywait(&sem2);
     426  status = sem_trywait(SEM_FAILED);
    218427  fatal_posix_service_status( status, -1, "sem_trywait error return status");
    219428  fatal_posix_service_status( errno, EINVAL, "sem_trywait errno EINVAL");
     
    257466
    258467  puts( "Init: sem_post - UNSUCCESSFUL (EINVAL)" );
    259   status = sem_post(&sem2);
     468  status = sem_post(SEM_FAILED);
    260469  fatal_posix_service_status( status, -1, "sem_post error return status");
    261470  fatal_posix_service_status( errno, EINVAL, "sem_post errno EINVAL");
     
    393602  rtems_test_assert( (status == -1) && (errno == ENOENT) );
    394603
     604  test_named_sem_wait_during_delete();
    395605  test_sem_wait_during_delete();
    396606  test_sem_post_overflow();
    397607  test_sem_init_too_large_inital_value();
     608  test_sem_null();
     609  test_sem_not_initialized();
     610  test_sem_invalid_copy();
    398611
    399612  /* Try adding in unlinking before closing... (can we still open?) */
     
    414627
    415628#define CONFIGURE_MAXIMUM_POSIX_THREADS     2
    416 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES  MAX_SEMS
     629#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES  2
    417630
    418631#define CONFIGURE_POSIX_INIT_THREAD_TABLE
  • testsuites/psxtmtests/psxtmsem02/init.c

    r47b1e31 rc090db7  
    160160
    161161#define CONFIGURE_MAXIMUM_POSIX_THREADS     1
    162 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES  2
    163162#define CONFIGURE_POSIX_INIT_THREAD_TABLE
    164163
  • testsuites/psxtmtests/psxtmsem03/init.c

    r47b1e31 rc090db7  
    125125
    126126#define CONFIGURE_MAXIMUM_POSIX_THREADS     OPERATION_COUNT + 2
    127 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES  MAX_SEMS
    128127#define CONFIGURE_POSIX_INIT_THREAD_TABLE
    129128
  • testsuites/psxtmtests/psxtmsem04/init.c

    r47b1e31 rc090db7  
    100100
    101101#define CONFIGURE_MAXIMUM_POSIX_THREADS     2
    102 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES  MAX_SEMS
    103102#define CONFIGURE_POSIX_INIT_THREAD_TABLE
    104103
  • testsuites/psxtmtests/psxtmsem05/init.c

    r47b1e31 rc090db7  
    160160
    161161#define CONFIGURE_MAXIMUM_POSIX_THREADS     OPERATION_COUNT + 2
    162 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES  MAX_SEMS
    163162#define CONFIGURE_POSIX_INIT_THREAD_TABLE
    164163
  • testsuites/sptests/spthreadq01/init.c

    r47b1e31 rc090db7  
    4141  rtems_id br;
    4242#if defined(RTEMS_POSIX_API)
    43   sem_t psem;
    4443  pthread_mutex_t pmtx;
    4544  pthread_cond_t pcv;
     
    120119  int eno;
    121120  char buf[1];
    122 
    123   wake_up_master(ctx);
    124   rtems_test_assert(get_wait_id(ctx) == ctx->psem);
    125 
    126   rv = sem_post(&ctx->psem);
    127   rtems_test_assert(rv == 0);
    128121
    129122  eno = pthread_mutex_lock(&ctx->pmtx);
     
    218211{
    219212#if defined(RTEMS_POSIX_API)
    220   int rv;
    221213  int eno;
    222214  struct mq_attr attr;
    223 
    224   rv = sem_init(&ctx->psem, 0, 0);
    225   rtems_test_assert(rv == 0);
    226215
    227216  eno = pthread_mutex_init(&ctx->pmtx, NULL);
     
    307296{
    308297#if defined(RTEMS_POSIX_API)
    309   int rv;
    310298  int eno;
    311299  char buf[1];
    312300  unsigned prio;
    313301  ssize_t n;
    314 
    315   wait_for_worker(ctx);
    316 
    317   rv = sem_wait(&ctx->psem);
    318   rtems_test_assert(rv == 0);
    319302
    320303  wait_for_worker(ctx);
     
    378361
    379362#if defined(RTEMS_POSIX_API)
    380   #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1
    381363  #define CONFIGURE_MAXIMUM_POSIX_MUTEXES 1
    382364  #define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 1
Note: See TracChangeset for help on using the changeset viewer.