summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-09-12 08:09:16 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-10-05 14:29:01 +0200
commitc090db7405b72ce6d0b726c0a39fb1c1aebab7ea (patch)
tree099a887f445115e9b40d25cd6a2b2b11908d347d /cpukit/posix/src
parentposix: Optimize pthread_once_t (diff)
downloadrtems-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.c14
-rw-r--r--cpukit/posix/src/semaphorecreatesupp.c102
-rw-r--r--cpukit/posix/src/semaphoredeletesupp.c13
-rw-r--r--cpukit/posix/src/semaphorewaitsupp.c53
-rw-r--r--cpukit/posix/src/semclose.c33
-rw-r--r--cpukit/posix/src/semdestroy.c31
-rw-r--r--cpukit/posix/src/semgetvalue.c33
-rw-r--r--cpukit/posix/src/seminit.c28
-rw-r--r--cpukit/posix/src/semopen.c86
-rw-r--r--cpukit/posix/src/sempost.c60
-rw-r--r--cpukit/posix/src/semtimedwait.c97
-rw-r--r--cpukit/posix/src/semtrywait.c36
-rw-r--r--cpukit/posix/src/semunlink.c13
-rw-r--r--cpukit/posix/src/semwait.c18
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;
}