diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-09-12 08:09:16 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-10-05 14:29:01 +0200 |
commit | c090db7405b72ce6d0b726c0a39fb1c1aebab7ea (patch) | |
tree | 099a887f445115e9b40d25cd6a2b2b11908d347d /cpukit/posix/src | |
parent | posix: Optimize pthread_once_t (diff) | |
download | rtems-c090db7405b72ce6d0b726c0a39fb1c1aebab7ea.tar.bz2 |
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.
Diffstat (limited to 'cpukit/posix/src')
-rw-r--r-- | cpukit/posix/src/semaphore.c | 14 | ||||
-rw-r--r-- | cpukit/posix/src/semaphorecreatesupp.c | 102 | ||||
-rw-r--r-- | cpukit/posix/src/semaphoredeletesupp.c | 13 | ||||
-rw-r--r-- | cpukit/posix/src/semaphorewaitsupp.c | 53 | ||||
-rw-r--r-- | cpukit/posix/src/semclose.c | 33 | ||||
-rw-r--r-- | cpukit/posix/src/semdestroy.c | 31 | ||||
-rw-r--r-- | cpukit/posix/src/semgetvalue.c | 33 | ||||
-rw-r--r-- | cpukit/posix/src/seminit.c | 28 | ||||
-rw-r--r-- | cpukit/posix/src/semopen.c | 86 | ||||
-rw-r--r-- | cpukit/posix/src/sempost.c | 60 | ||||
-rw-r--r-- | cpukit/posix/src/semtimedwait.c | 97 | ||||
-rw-r--r-- | cpukit/posix/src/semtrywait.c | 36 | ||||
-rw-r--r-- | cpukit/posix/src/semunlink.c | 13 | ||||
-rw-r--r-- | cpukit/posix/src/semwait.c | 18 |
14 files changed, 224 insertions, 393 deletions
diff --git a/cpukit/posix/src/semaphore.c b/cpukit/posix/src/semaphore.c index 661456c748..a82ad17966 100644 --- a/cpukit/posix/src/semaphore.c +++ b/cpukit/posix/src/semaphore.c @@ -18,19 +18,11 @@ #include "config.h" #endif -#include <stdarg.h> - -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <semaphore.h> -#include <limits.h> - -#include <rtems/system.h> +#include <rtems/posix/semaphoreimpl.h> #include <rtems/config.h> #include <rtems/sysinit.h> -#include <rtems/posix/semaphoreimpl.h> -#include <rtems/seterr.h> + +#include <limits.h> Objects_Information _POSIX_Semaphore_Information; diff --git a/cpukit/posix/src/semaphorecreatesupp.c b/cpukit/posix/src/semaphorecreatesupp.c deleted file mode 100644 index 4a33336230..0000000000 --- a/cpukit/posix/src/semaphorecreatesupp.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file - * - * @brief Function does Actual creation and Initialization of POSIX Semaphore - * @ingroup POSIXAPI - */ - -/* - * COPYRIGHT (c) 1989-2009. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdarg.h> - -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <semaphore.h> -#include <limits.h> -#include <string.h> /* strlen */ - -#include <rtems/system.h> -#include <rtems/score/wkspace.h> -#include <rtems/posix/semaphoreimpl.h> -#include <rtems/seterr.h> - -/* - * _POSIX_Semaphore_Create_support - * - * This routine does the actual creation and initialization of - * a poxix semaphore. It is a support routine for sem_init and - * sem_open. - */ -int _POSIX_Semaphore_Create_support( - const char *name_arg, - size_t name_len, - unsigned int value, - POSIX_Semaphore_Control **the_sem -) -{ - POSIX_Semaphore_Control *the_semaphore; - char *name; - - /* - * Make a copy of the user's string for name just in case it was - * dynamically constructed. - */ - if ( name_arg != NULL ) { - name = _Workspace_String_duplicate( name_arg, name_len ); - if ( !name ) { - rtems_set_errno_and_return_minus_one( ENOMEM ); - } - } else { - name = NULL; - } - - the_semaphore = _POSIX_Semaphore_Allocate_unprotected(); - if ( !the_semaphore ) { - _Workspace_Free( name ); - rtems_set_errno_and_return_minus_one( ENOSPC ); - } - - if ( name ) { - the_semaphore->named = true; - the_semaphore->open_count = 1; - the_semaphore->linked = true; - } else { - the_semaphore->named = false; - the_semaphore->open_count = 0; - the_semaphore->linked = false; - } - - /* - * POSIX does not appear to specify what the discipline for - * blocking tasks on this semaphore should be. It could somehow - * be derived from the current scheduling policy. One - * thing is certain, no matter what we decide, it won't be - * the same as all other POSIX implementations. :) - */ - _CORE_semaphore_Initialize( &the_semaphore->Semaphore, value ); - - /* - * Make the semaphore available for use. - */ - _Objects_Open_string( - &_POSIX_Semaphore_Information, - &the_semaphore->Object, - name - ); - - *the_sem = the_semaphore; - - return 0; -} diff --git a/cpukit/posix/src/semaphoredeletesupp.c b/cpukit/posix/src/semaphoredeletesupp.c index 325e4a6c1b..dbcfebfd65 100644 --- a/cpukit/posix/src/semaphoredeletesupp.c +++ b/cpukit/posix/src/semaphoredeletesupp.c @@ -20,20 +20,11 @@ #include <rtems/posix/semaphoreimpl.h> -void _POSIX_Semaphore_Delete( - POSIX_Semaphore_Control *the_semaphore, - Thread_queue_Context *queue_context -) +void _POSIX_Semaphore_Delete( POSIX_Semaphore_Control *the_semaphore ) { if ( !the_semaphore->linked && !the_semaphore->open_count ) { _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object ); - _CORE_semaphore_Destroy( - &the_semaphore->Semaphore, - POSIX_SEMAPHORE_TQ_OPERATIONS, - queue_context - ); + _POSIX_Semaphore_Destroy( &the_semaphore->Semaphore ); _POSIX_Semaphore_Free( the_semaphore ); - } else { - _CORE_semaphore_Release( &the_semaphore->Semaphore, queue_context ); } } diff --git a/cpukit/posix/src/semaphorewaitsupp.c b/cpukit/posix/src/semaphorewaitsupp.c deleted file mode 100644 index a4c43fd704..0000000000 --- a/cpukit/posix/src/semaphorewaitsupp.c +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file - * - * @brief POSIX Semaphore Wait Support - * @ingroup POSIXSemaphorePrivate - */ - -/* - * COPYRIGHT (c) 1989-2012. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <semaphore.h> - -#include <rtems/posix/semaphoreimpl.h> -#include <rtems/posix/posixapi.h> - -THREAD_QUEUE_OBJECT_ASSERT( POSIX_Semaphore_Control, Semaphore.Wait_queue ); - -int _POSIX_Semaphore_Wait_support( - sem_t *sem, - bool blocking, - Watchdog_Interval timeout -) -{ - POSIX_Semaphore_Control *the_semaphore; - Thread_queue_Context queue_context; - Status_Control status; - - the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context ); - - if ( the_semaphore == NULL ) { - rtems_set_errno_and_return_minus_one( EINVAL ); - } - - _Thread_queue_Context_set_relative_timeout( &queue_context, timeout ); - status = _CORE_semaphore_Seize( - &the_semaphore->Semaphore, - POSIX_SEMAPHORE_TQ_OPERATIONS, - _Thread_Executing, - blocking, - &queue_context - ); - return _POSIX_Zero_or_minus_one_plus_errno( status ); -} diff --git a/cpukit/posix/src/semclose.c b/cpukit/posix/src/semclose.c index ebcf7a26b3..a27b165350 100644 --- a/cpukit/posix/src/semclose.c +++ b/cpukit/posix/src/semclose.c @@ -18,32 +18,37 @@ #include "config.h" #endif -#include <semaphore.h> - #include <rtems/posix/semaphoreimpl.h> -int sem_close( - sem_t *sem -) +int sem_close( sem_t *sem ) { POSIX_Semaphore_Control *the_semaphore; - Thread_queue_Context queue_context; + uint32_t open_count; + + POSIX_SEMAPHORE_VALIDATE_OBJECT( sem ); + + if ( !_POSIX_Semaphore_Is_named( sem ) ) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + the_semaphore = _POSIX_Semaphore_Get( sem ); _Objects_Allocator_lock(); - the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context ); - if ( the_semaphore == NULL ) { + open_count = the_semaphore->open_count; + + if ( open_count == 0 ) { _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( EINVAL ); } - _CORE_semaphore_Acquire_critical( - &the_semaphore->Semaphore, - &queue_context - ); - the_semaphore->open_count -= 1; - _POSIX_Semaphore_Delete( the_semaphore, &queue_context ); + if ( open_count == 1 && _POSIX_Semaphore_Is_busy( sem ) ) { + _Objects_Allocator_unlock(); + rtems_set_errno_and_return_minus_one( EBUSY ); + } + the_semaphore->open_count = open_count - 1; + _POSIX_Semaphore_Delete( the_semaphore ); _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/semdestroy.c b/cpukit/posix/src/semdestroy.c index 8b81470bbf..61f5b1e80f 100644 --- a/cpukit/posix/src/semdestroy.c +++ b/cpukit/posix/src/semdestroy.c @@ -18,39 +18,20 @@ #include "config.h" #endif -#include <semaphore.h> - #include <rtems/posix/semaphoreimpl.h> -int sem_destroy( - sem_t *sem -) +int sem_destroy( sem_t *sem ) { - POSIX_Semaphore_Control *the_semaphore; - Thread_queue_Context queue_context; - - _Objects_Allocator_lock(); - the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context ); + POSIX_SEMAPHORE_VALIDATE_OBJECT( sem ); - if ( the_semaphore == NULL ) { - _Objects_Allocator_unlock(); + if ( _POSIX_Semaphore_Is_named( sem ) ) { rtems_set_errno_and_return_minus_one( EINVAL ); } - _CORE_semaphore_Acquire_critical( - &the_semaphore->Semaphore, - &queue_context - ); - - if ( the_semaphore->named ) { - /* Undefined operation on a named semaphore */ - _CORE_semaphore_Release( &the_semaphore->Semaphore, &queue_context ); - _Objects_Allocator_unlock(); - rtems_set_errno_and_return_minus_one( EINVAL ); + if ( _POSIX_Semaphore_Is_busy( sem ) ) { + rtems_set_errno_and_return_minus_one( EBUSY ); } - _POSIX_Semaphore_Delete( the_semaphore, &queue_context ); - - _Objects_Allocator_unlock(); + _POSIX_Semaphore_Destroy( sem ); return 0; } diff --git a/cpukit/posix/src/semgetvalue.c b/cpukit/posix/src/semgetvalue.c index 1b752944fa..f0242f2ca8 100644 --- a/cpukit/posix/src/semgetvalue.c +++ b/cpukit/posix/src/semgetvalue.c @@ -18,31 +18,24 @@ #include "config.h" #endif -#include <semaphore.h> - #include <rtems/posix/semaphoreimpl.h> int sem_getvalue( - sem_t *__restrict sem, + sem_t *__restrict _sem, int *__restrict sval ) { - POSIX_Semaphore_Control *the_semaphore; - Thread_queue_Context queue_context; - - the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context ); - - if ( the_semaphore == NULL ) { - rtems_set_errno_and_return_minus_one( EINVAL ); - } - - _CORE_semaphore_Acquire_critical( - &the_semaphore->Semaphore, - &queue_context - ); - - *sval = _CORE_semaphore_Get_count( &the_semaphore->Semaphore ); - - _CORE_semaphore_Release( &the_semaphore->Semaphore, &queue_context ); + Sem_Control *sem; + ISR_Level level; + Thread_queue_Context queue_context; + + POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem ); + + sem = _Sem_Get( &_sem->_Semaphore ); + _Thread_queue_Context_initialize( &queue_context ); + _Thread_queue_Context_ISR_disable( &queue_context, level ); + _Sem_Queue_acquire_critical( sem, &queue_context ); + *sval = (int) sem->count; + _Sem_Queue_release( sem, level, &queue_context ); return 0; } diff --git a/cpukit/posix/src/seminit.c b/cpukit/posix/src/seminit.c index cf06f6ce41..65104ad2c7 100644 --- a/cpukit/posix/src/seminit.c +++ b/cpukit/posix/src/seminit.c @@ -18,17 +18,11 @@ #include "config.h" #endif -#include <stdarg.h> +#include <rtems/posix/semaphoreimpl.h> -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <semaphore.h> #include <limits.h> -#include <rtems/system.h> -#include <rtems/posix/semaphoreimpl.h> -#include <rtems/seterr.h> +RTEMS_STATIC_ASSERT(NULL == SEM_FAILED, sem_failed); /* * 11.2.1 Initialize an Unnamed Semaphore, P1003.1b-1993, p.219 @@ -40,9 +34,6 @@ int sem_init( unsigned int value ) { - int status; - POSIX_Semaphore_Control *the_semaphore; - if ( sem == NULL ) { rtems_set_errno_and_return_minus_one( EINVAL ); } @@ -51,17 +42,6 @@ int sem_init( rtems_set_errno_and_return_minus_one( EINVAL ); } - _Objects_Allocator_lock(); - status = _POSIX_Semaphore_Create_support( - NULL, - 0, - value, - &the_semaphore - ); - _Objects_Allocator_unlock(); - - if ( status != -1 ) - *sem = the_semaphore->Object.id; - - return status; + _POSIX_Semaphore_Initialize( sem, NULL, value ); + return 0; } diff --git a/cpukit/posix/src/semopen.c b/cpukit/posix/src/semopen.c index 98163cca8d..63915fca57 100644 --- a/cpukit/posix/src/semopen.c +++ b/cpukit/posix/src/semopen.c @@ -18,17 +18,64 @@ #include "config.h" #endif -#include <stdarg.h> +#include <rtems/posix/semaphoreimpl.h> +#include <rtems/score/wkspace.h> -#include <errno.h> +#include <stdarg.h> #include <fcntl.h> -#include <pthread.h> -#include <semaphore.h> #include <limits.h> -#include <rtems/system.h> -#include <rtems/posix/semaphoreimpl.h> -#include <rtems/seterr.h> +static sem_t *_POSIX_Semaphore_Create_support( + const char *name_arg, + size_t name_len, + unsigned int value +) +{ + POSIX_Semaphore_Control *the_semaphore; + char *name; + + if ( value > SEM_VALUE_MAX ) { + rtems_set_errno_and_return_value( EINVAL, SEM_FAILED ); + } + + /* + * Make a copy of the user's string for name just in case it was + * dynamically constructed. + */ + name = _Workspace_String_duplicate( name_arg, name_len ); + if ( name == NULL ) { + rtems_set_errno_and_return_value( ENOMEM, SEM_FAILED ); + } + + the_semaphore = _POSIX_Semaphore_Allocate_unprotected(); + if ( the_semaphore == NULL ) { + _Workspace_Free( name ); + rtems_set_errno_and_return_value( ENOSPC, SEM_FAILED ); + } + + the_semaphore->open_count = 1; + the_semaphore->linked = true; + + /* + * POSIX does not appear to specify what the discipline for + * blocking tasks on this semaphore should be. It could somehow + * be derived from the current scheduling policy. One + * thing is certain, no matter what we decide, it won't be + * the same as all other POSIX implementations. :) + */ + _POSIX_Semaphore_Initialize( &the_semaphore->Semaphore, name, value ); + + /* + * Make the semaphore available for use. + */ + _Objects_Open_string( + &_POSIX_Semaphore_Information, + &the_semaphore->Object, + name + ); + + return &the_semaphore->Semaphore; +} /* * sem_open @@ -59,10 +106,10 @@ sem_t *sem_open( va_list arg; unsigned int value = 0; - int status; POSIX_Semaphore_Control *the_semaphore; size_t name_len; Objects_Get_by_name_error error; + sem_t *sem; if ( oflag & O_CREAT ) { va_start(arg, oflag); @@ -108,7 +155,7 @@ sem_t *sem_open( the_semaphore->open_count += 1; _Objects_Allocator_unlock(); - goto return_id; + return &the_semaphore->Semaphore; } /* @@ -116,27 +163,12 @@ sem_t *sem_open( * checked. We should go ahead and create a semaphore. */ - status =_POSIX_Semaphore_Create_support( + sem = _POSIX_Semaphore_Create_support( name, name_len, - value, - &the_semaphore + value ); - /* - * errno was set by Create_support, so don't set it again. - */ - _Objects_Allocator_unlock(); - - if ( status != 0 ) - return SEM_FAILED; - -return_id: - #if defined(RTEMS_USE_16_BIT_OBJECT) - the_semaphore->Semaphore_id = the_semaphore->Object.id; - return &the_semaphore->Semaphore_id; - #else - return &the_semaphore->Object.id; - #endif + return sem; } diff --git a/cpukit/posix/src/sempost.c b/cpukit/posix/src/sempost.c index da2b1a5495..de0ae71fc7 100644 --- a/cpukit/posix/src/sempost.c +++ b/cpukit/posix/src/sempost.c @@ -18,31 +18,51 @@ #include "config.h" #endif -#include <semaphore.h> -#include <limits.h> - #include <rtems/posix/semaphoreimpl.h> -#include <rtems/posix/posixapi.h> -int sem_post( - sem_t *sem -) +#include <limits.h> + +int sem_post( sem_t *_sem ) { - POSIX_Semaphore_Control *the_semaphore; - Thread_queue_Context queue_context; - Status_Control status; + Sem_Control *sem; + ISR_Level level; + Thread_queue_Context queue_context; + Thread_queue_Heads *heads; + unsigned int count; + + POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem ); + + sem = _Sem_Get( &_sem->_Semaphore ); + _Thread_queue_Context_initialize( &queue_context ); + _Thread_queue_Context_ISR_disable( &queue_context, level ); + _Sem_Queue_acquire_critical( sem, &queue_context ); + + heads = sem->Queue.Queue.heads; + count = sem->count; + + if ( __predict_true( heads == NULL && count < SEM_VALUE_MAX ) ) { + sem->count = count + 1; + _Sem_Queue_release( sem, level, &queue_context ); + return 0; + } + + if ( __predict_true( heads != NULL ) ) { + const Thread_queue_Operations *operations; + Thread_Control *first; - the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context ); + _Thread_queue_Context_set_ISR_level( &queue_context, level ); + operations = SEMAPHORE_TQ_OPERATIONS; + first = ( *operations->first )( heads ); - if ( the_semaphore == NULL ) { - rtems_set_errno_and_return_minus_one( EINVAL ); + _Thread_queue_Extract_critical( + &sem->Queue.Queue, + operations, + first, + &queue_context + ); + return 0; } - status = _CORE_semaphore_Surrender( - &the_semaphore->Semaphore, - POSIX_SEMAPHORE_TQ_OPERATIONS, - SEM_VALUE_MAX, - &queue_context - ); - return _POSIX_Zero_or_minus_one_plus_errno( status ); + _Sem_Queue_release( sem, level, &queue_context ); + rtems_set_errno_and_return_minus_one( EOVERFLOW ); } diff --git a/cpukit/posix/src/semtimedwait.c b/cpukit/posix/src/semtimedwait.c index 09028f4d08..f00557c38d 100644 --- a/cpukit/posix/src/semtimedwait.c +++ b/cpukit/posix/src/semtimedwait.c @@ -18,18 +18,8 @@ #include "config.h" #endif -#include <stdarg.h> - -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <semaphore.h> -#include <limits.h> - -#include <rtems/system.h> -#include <rtems/score/todimpl.h> #include <rtems/posix/semaphoreimpl.h> -#include <rtems/seterr.h> +#include <rtems/score/todimpl.h> /* * 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226 @@ -38,47 +28,60 @@ */ int sem_timedwait( - sem_t *__restrict sem, + sem_t *__restrict _sem, const struct timespec *__restrict abstime ) { - Watchdog_Interval ticks; - bool do_wait = true; - TOD_Absolute_timeout_conversion_results status; - int lock_status; + Sem_Control *sem; + Thread_queue_Context queue_context; + ISR_Level level; + Thread_Control *executing; + unsigned int count; - /* - * POSIX requires that blocking calls with timeouts that take - * an absolute timeout must ignore issues with the absolute - * time provided if the operation would otherwise succeed. - * So we check the abstime provided, and hold on to whether it - * is valid or not. If it isn't correct and in the future, - * then we do a polling operation and convert the UNSATISFIED - * status into the appropriate error. - * - * If the status is TOD_ABSOLUTE_TIMEOUT_INVALID, - * TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW, - * then we should not wait. - */ - status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ); - if ( status != TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE ) - do_wait = false; + POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem ); - lock_status = _POSIX_Semaphore_Wait_support( sem, do_wait, ticks ); + sem = _Sem_Get( &_sem->_Semaphore ); + _Thread_queue_Context_initialize( &queue_context ); + _Thread_queue_Context_ISR_disable( &queue_context, level ); + executing = _Sem_Queue_acquire_critical( sem, &queue_context ); - /* - * This service only gives us the option to block. We used a polling - * attempt to obtain if the abstime was not in the future. If we did - * not obtain the semaphore, then not look at the status immediately, - * make sure the right reason is returned. - */ - if ( !do_wait && (lock_status == EBUSY) ) { - if ( lock_status == TOD_ABSOLUTE_TIMEOUT_INVALID ) - rtems_set_errno_and_return_minus_one( EINVAL ); - if ( lock_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST || - lock_status == TOD_ABSOLUTE_TIMEOUT_IS_NOW ) - rtems_set_errno_and_return_minus_one( ETIMEDOUT ); - } + count = sem->count; + if ( __predict_true( count > 0 ) ) { + sem->count = count - 1; + _Sem_Queue_release( sem, level, &queue_context ); + return 0; + } else { + Watchdog_Interval ticks; + Status_Control status; + + switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) { + case TOD_ABSOLUTE_TIMEOUT_INVALID: + _Sem_Queue_release( sem, level, &queue_context ); + rtems_set_errno_and_return_minus_one( EINVAL ); + break; + case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST: + case TOD_ABSOLUTE_TIMEOUT_IS_NOW: + _Sem_Queue_release( sem, level, &queue_context ); + rtems_set_errno_and_return_minus_one( ETIMEDOUT ); + break; + default: + break; + } - return lock_status; + _Thread_queue_Context_set_thread_state( + &queue_context, + STATES_WAITING_FOR_SEMAPHORE + ); + _Thread_queue_Context_set_do_nothing_enqueue_callout( &queue_context ); + _Thread_queue_Context_set_relative_timeout( &queue_context, ticks ); + _Thread_queue_Context_set_ISR_level( &queue_context, level ); + _Thread_queue_Enqueue( + &sem->Queue.Queue, + SEMAPHORE_TQ_OPERATIONS, + executing, + &queue_context + ); + status = _Thread_Wait_get_status( executing ); + return _POSIX_Zero_or_minus_one_plus_errno( status ); + } } diff --git a/cpukit/posix/src/semtrywait.c b/cpukit/posix/src/semtrywait.c index a6836d8eaf..673343d4b4 100644 --- a/cpukit/posix/src/semtrywait.c +++ b/cpukit/posix/src/semtrywait.c @@ -18,21 +18,29 @@ #include "config.h" #endif -#include <stdarg.h> - -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <semaphore.h> -#include <limits.h> - -#include <rtems/system.h> #include <rtems/posix/semaphoreimpl.h> -#include <rtems/seterr.h> -int sem_trywait( - sem_t *sem -) +int sem_trywait( sem_t *_sem ) { - return _POSIX_Semaphore_Wait_support(sem, false, WATCHDOG_NO_TIMEOUT); + Sem_Control *sem; + Thread_queue_Context queue_context; + ISR_Level level; + unsigned int count; + + POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem ); + + sem = _Sem_Get( &_sem->_Semaphore ); + _Thread_queue_Context_initialize( &queue_context ); + _Thread_queue_Context_ISR_disable( &queue_context, level ); + _Sem_Queue_acquire_critical( sem, &queue_context ); + + count = sem->count; + if ( __predict_true( count > 0 ) ) { + sem->count = count - 1; + _Sem_Queue_release( sem, level, &queue_context ); + return 0; + } else { + _Sem_Queue_release( sem, level, &queue_context ); + rtems_set_errno_and_return_minus_one( EAGAIN ); + } } diff --git a/cpukit/posix/src/semunlink.c b/cpukit/posix/src/semunlink.c index 02fcdcab1b..2abc8f9435 100644 --- a/cpukit/posix/src/semunlink.c +++ b/cpukit/posix/src/semunlink.c @@ -18,17 +18,12 @@ #include "config.h" #endif -#include <semaphore.h> - #include <rtems/posix/semaphoreimpl.h> -int sem_unlink( - const char *name -) +int sem_unlink( const char *name ) { POSIX_Semaphore_Control *the_semaphore; Objects_Get_by_name_error error; - Thread_queue_Context queue_context; _Objects_Allocator_lock(); @@ -39,12 +34,8 @@ int sem_unlink( } _POSIX_Semaphore_Namespace_remove( the_semaphore ); - - _ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context ); - _CORE_semaphore_Acquire_critical( &the_semaphore->Semaphore, &queue_context ); the_semaphore->linked = false; - _POSIX_Semaphore_Delete( the_semaphore, &queue_context ); - + _POSIX_Semaphore_Delete( the_semaphore ); _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/semwait.c b/cpukit/posix/src/semwait.c index 30cf5ad344..0353af4029 100644 --- a/cpukit/posix/src/semwait.c +++ b/cpukit/posix/src/semwait.c @@ -18,21 +18,11 @@ #include "config.h" #endif -#include <stdarg.h> - -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <semaphore.h> -#include <limits.h> - -#include <rtems/system.h> #include <rtems/posix/semaphoreimpl.h> -#include <rtems/seterr.h> -int sem_wait( - sem_t *sem -) +int sem_wait( sem_t *sem ) { - return _POSIX_Semaphore_Wait_support( sem, true, WATCHDOG_NO_TIMEOUT ); + POSIX_SEMAPHORE_VALIDATE_OBJECT( sem ); + _Semaphore_Wait( &sem->_Semaphore ); + return 0; } |