summaryrefslogtreecommitdiffstats
path: root/cpukit
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
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')
-rw-r--r--cpukit/posix/Makefile.am24
-rw-r--r--cpukit/posix/include/rtems/posix/semaphore.h18
-rw-r--r--cpukit/posix/include/rtems/posix/semaphoreimpl.h82
-rw-r--r--cpukit/posix/preinstall.am16
-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
-rw-r--r--cpukit/sapi/src/posixapi.c25
-rw-r--r--cpukit/score/Makefile.am1
-rw-r--r--cpukit/score/include/rtems/score/semaphoreimpl.h73
-rw-r--r--cpukit/score/preinstall.am4
-rw-r--r--cpukit/score/src/semaphore.c73
23 files changed, 412 insertions, 521 deletions
diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am
index 3bb5bd29f9..1d9e209101 100644
--- a/cpukit/posix/Makefile.am
+++ b/cpukit/posix/Makefile.am
@@ -21,6 +21,8 @@ include_rtems_posix_HEADERS += include/rtems/posix/keyimpl.h
include_rtems_posix_HEADERS += include/rtems/posix/config.h
include_rtems_posix_HEADERS += include/rtems/posix/posixapi.h
include_rtems_posix_HEADERS += include/rtems/posix/priorityimpl.h
+include_rtems_posix_HEADERS += include/rtems/posix/semaphore.h
+include_rtems_posix_HEADERS += include/rtems/posix/semaphoreimpl.h
include_rtems_posix_HEADERS += include/rtems/posix/spinlockimpl.h
if HAS_PTHREADS
@@ -44,8 +46,6 @@ include_rtems_posix_HEADERS += include/rtems/posix/pthreadimpl.h
include_rtems_posix_HEADERS += include/rtems/posix/ptimer.h
include_rtems_posix_HEADERS += include/rtems/posix/shm.h
include_rtems_posix_HEADERS += include/rtems/posix/shmimpl.h
-include_rtems_posix_HEADERS += include/rtems/posix/semaphore.h
-include_rtems_posix_HEADERS += include/rtems/posix/semaphoreimpl.h
include_rtems_posix_HEADERS += include/rtems/posix/threadsup.h
include_rtems_posix_HEADERS += include/rtems/posix/timer.h
include_rtems_posix_HEADERS += include/rtems/posix/timerimpl.h
@@ -186,6 +186,15 @@ libposix_a_SOURCES += src/pspininit.c
libposix_a_SOURCES += src/pspinlock.c
libposix_a_SOURCES += src/pspinunlock.c
+## SEMAPHORE_C_FILES
+libposix_a_SOURCES += src/semdestroy.c
+libposix_a_SOURCES += src/semgetvalue.c
+libposix_a_SOURCES += src/seminit.c
+libposix_a_SOURCES += src/sempost.c
+libposix_a_SOURCES += src/semtimedwait.c
+libposix_a_SOURCES += src/semtrywait.c
+libposix_a_SOURCES += src/semwait.c
+
if HAS_PTHREADS
libposix_a_SOURCES += src/sigpending.c \
src/sigqueue.c src/sigsuspend.c src/sigtimedwait.c \
@@ -199,12 +208,11 @@ libposix_a_SOURCES += src/prwlock.c src/prwlockdestroy.c src/prwlockinit.c \
src/rwlockattrinit.c src/rwlockattrsetpshared.c
## SEMAPHORE_C_FILES
-libposix_a_SOURCES += src/semaphore.c src/semaphorecreatesupp.c \
- src/semaphoredeletesupp.c \
- src/semaphorewaitsupp.c \
- src/semclose.c src/semdestroy.c src/semgetvalue.c src/seminit.c \
- src/semopen.c src/sempost.c src/semtimedwait.c src/semtrywait.c \
- src/semunlink.c src/semwait.c
+libposix_a_SOURCES += src/semaphore.c
+libposix_a_SOURCES += src/semaphoredeletesupp.c
+libposix_a_SOURCES += src/semclose.c
+libposix_a_SOURCES += src/semopen.c
+libposix_a_SOURCES += src/semunlink.c
## TIME_C_FILES
libposix_a_SOURCES += src/adjtime.c src/clockgetcpuclockid.c
diff --git a/cpukit/posix/include/rtems/posix/semaphore.h b/cpukit/posix/include/rtems/posix/semaphore.h
index 6598397052..9133db22be 100644
--- a/cpukit/posix/include/rtems/posix/semaphore.h
+++ b/cpukit/posix/include/rtems/posix/semaphore.h
@@ -21,7 +21,6 @@
#include <semaphore.h>
#include <rtems/score/object.h>
-#include <rtems/score/coresem.h>
#ifdef __cplusplus
extern "C" {
@@ -41,19 +40,10 @@ extern "C" {
*/
typedef struct {
- Objects_Control Object;
- CORE_semaphore_Control Semaphore;
- bool named;
- bool linked;
- uint32_t open_count;
- /*
- * sem_t is 32-bit. If Object_Id is 16-bit, then they are not
- * interchangeable. We have to be able to return a pointer to
- * a 32-bit form of the 16-bit Id.
- */
- #if defined(RTEMS_USE_16_BIT_OBJECT)
- sem_t Semaphore_id;
- #endif
+ Objects_Control Object;
+ sem_t Semaphore;
+ bool linked;
+ uint32_t open_count;
} POSIX_Semaphore_Control;
/** @} */
diff --git a/cpukit/posix/include/rtems/posix/semaphoreimpl.h b/cpukit/posix/include/rtems/posix/semaphoreimpl.h
index 43440298ec..fd17743699 100644
--- a/cpukit/posix/include/rtems/posix/semaphoreimpl.h
+++ b/cpukit/posix/include/rtems/posix/semaphoreimpl.h
@@ -21,7 +21,7 @@
#include <rtems/posix/semaphore.h>
#include <rtems/posix/posixapi.h>
-#include <rtems/score/coresemimpl.h>
+#include <rtems/score/semaphoreimpl.h>
#include <rtems/seterr.h>
#ifdef __cplusplus
@@ -29,13 +29,17 @@ extern "C" {
#endif
/**
+ * @brief This is a random number used to check if a semaphore object is
+ * properly initialized.
+ */
+#define POSIX_SEMAPHORE_MAGIC 0x5d367fe7UL
+
+/**
* This defines the information control block used to manage
* this class of objects.
*/
extern Objects_Information _POSIX_Semaphore_Information;
-#define POSIX_SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
-
RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *
_POSIX_Semaphore_Allocate_unprotected( void )
{
@@ -57,54 +61,46 @@ RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free (
}
RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get(
- const sem_t *id,
- Thread_queue_Context *queue_context
+ sem_t *sem
)
{
- _Thread_queue_Context_initialize( queue_context );
- return (POSIX_Semaphore_Control *) _Objects_Get(
- (Objects_Id) *id,
- &queue_context->Lock_context.Lock_context,
- &_POSIX_Semaphore_Information
- );
+ return RTEMS_CONTAINER_OF( sem, POSIX_Semaphore_Control, Semaphore );
}
-/**
- * @brief POSIX Semaphore Create Support
- *
- * This routine supports the sem_init and sem_open routines.
- */
+RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_named( const sem_t *sem )
+{
+ return sem->_Semaphore._Queue._name != NULL;
+}
-int _POSIX_Semaphore_Create_support(
- const char *name,
- size_t name_len,
- unsigned int value,
- POSIX_Semaphore_Control **the_sem
-);
+RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_busy( const sem_t *sem )
+{
+ return sem->_Semaphore._Queue._heads != NULL;
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Initialize(
+ sem_t *sem,
+ const char *name,
+ unsigned int value
+)
+{
+ sem->_flags = (uintptr_t) sem ^ POSIX_SEMAPHORE_MAGIC;
+ _Semaphore_Initialize_named( &sem->_Semaphore, name, value );
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Destroy( sem_t *sem )
+{
+ sem->_flags = 0;
+ _Semaphore_Destroy( &sem->_Semaphore );
+}
/**
* @brief POSIX Semaphore Delete
*
* This routine supports the sem_close and sem_unlink routines.
*/
-void _POSIX_Semaphore_Delete(
- POSIX_Semaphore_Control *the_semaphore,
- Thread_queue_Context *queue_context
-);
+void _POSIX_Semaphore_Delete( POSIX_Semaphore_Control *the_semaphore );
/**
- * @brief POSIX semaphore wait support.
- *
- * This routine supports the sem_wait, sem_trywait, and sem_timedwait
- * services.
- */
-int _POSIX_Semaphore_Wait_support(
- sem_t *sem,
- bool blocking,
- Watchdog_Interval timeout
-);
-
-/**
* @brief POSIX Semaphore Namespace Remove
*/
RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Namespace_remove (
@@ -129,6 +125,16 @@ RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get_by_name(
);
}
+#define POSIX_SEMAPHORE_VALIDATE_OBJECT( sem ) \
+ do { \
+ if ( \
+ ( sem ) == NULL \
+ || ( (uintptr_t) ( sem ) ^ POSIX_SEMAPHORE_MAGIC ) != ( sem )->_flags \
+ ) { \
+ rtems_set_errno_and_return_minus_one( EINVAL ); \
+ } \
+ } while ( 0 )
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/posix/preinstall.am b/cpukit/posix/preinstall.am
index cfb087c923..d67f9face8 100644
--- a/cpukit/posix/preinstall.am
+++ b/cpukit/posix/preinstall.am
@@ -47,6 +47,14 @@ $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h: include/rtems/posix/priorityimpl.
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/priorityimpl.h
+$(PROJECT_INCLUDE)/rtems/posix/semaphore.h: include/rtems/posix/semaphore.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
+
+$(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h: include/rtems/posix/semaphoreimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
+
$(PROJECT_INCLUDE)/rtems/posix/spinlockimpl.h: include/rtems/posix/spinlockimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/spinlockimpl.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/spinlockimpl.h
@@ -120,14 +128,6 @@ $(PROJECT_INCLUDE)/rtems/posix/shmimpl.h: include/rtems/posix/shmimpl.h $(PROJEC
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/shmimpl.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/shmimpl.h
-$(PROJECT_INCLUDE)/rtems/posix/semaphore.h: include/rtems/posix/semaphore.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.h
-
-$(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h: include/rtems/posix/semaphoreimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphoreimpl.h
-
$(PROJECT_INCLUDE)/rtems/posix/threadsup.h: include/rtems/posix/threadsup.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/threadsup.h
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;
}
diff --git a/cpukit/sapi/src/posixapi.c b/cpukit/sapi/src/posixapi.c
index e7d34fdf60..ef725bea96 100644
--- a/cpukit/sapi/src/posixapi.c
+++ b/cpukit/sapi/src/posixapi.c
@@ -20,6 +20,31 @@
#endif
#include <rtems/posix/posixapi.h>
+#include <rtems/posix/semaphoreimpl.h>
+#include <rtems/score/heap.h>
+
+#ifdef HEAP_PROTECTION
+RTEMS_STATIC_ASSERT(
+ POSIX_SEMAPHORE_MAGIC != HEAP_BEGIN_PROTECTOR_0,
+ POSIX_SEMAPHORE_MAGIC_0
+);
+RTEMS_STATIC_ASSERT(
+ POSIX_SEMAPHORE_MAGIC != HEAP_BEGIN_PROTECTOR_1,
+ POSIX_SEMAPHORE_MAGIC_1
+);
+RTEMS_STATIC_ASSERT(
+ POSIX_SEMAPHORE_MAGIC != HEAP_END_PROTECTOR_0,
+ POSIX_SEMAPHORE_MAGIC_2
+);
+RTEMS_STATIC_ASSERT(
+ POSIX_SEMAPHORE_MAGIC != HEAP_END_PROTECTOR_1,
+ POSIX_SEMAPHORE_MAGIC_3
+);
+RTEMS_STATIC_ASSERT(
+ POSIX_SEMAPHORE_MAGIC != HEAP_FREE_PATTERN,
+ POSIX_SEMAPHORE_MAGIC_4
+);
+#endif
void _POSIX_Fatal_error( POSIX_Fatal_domain domain, int eno )
{
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index d2dd80d6f0..03a15e3b09 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -80,6 +80,7 @@ include_rtems_score_HEADERS += include/rtems/score/schedulersimple.h
include_rtems_score_HEADERS += include/rtems/score/schedulersimpleimpl.h
include_rtems_score_HEADERS += include/rtems/score/schedulersmp.h
include_rtems_score_HEADERS += include/rtems/score/schedulersmpimpl.h
+include_rtems_score_HEADERS += include/rtems/score/semaphoreimpl.h
include_rtems_score_HEADERS += include/rtems/score/smp.h
include_rtems_score_HEADERS += include/rtems/score/smpbarrier.h
include_rtems_score_HEADERS += include/rtems/score/smplock.h
diff --git a/cpukit/score/include/rtems/score/semaphoreimpl.h b/cpukit/score/include/rtems/score/semaphoreimpl.h
new file mode 100644
index 0000000000..a7857db93e
--- /dev/null
+++ b/cpukit/score/include/rtems/score/semaphoreimpl.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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.
+ */
+
+#ifndef _RTEMS_SCORE_SEMAPHOREIMPL_H
+#define _RTEMS_SCORE_SEMAPHOREIMPL_H
+
+#include <sys/lock.h>
+
+#include <rtems/score/percpu.h>
+#include <rtems/score/threadqimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct {
+ Thread_queue_Syslock_queue Queue;
+ unsigned int count;
+} Sem_Control;
+
+#define SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_priority
+
+static inline Sem_Control *_Sem_Get( struct _Semaphore_Control *_sem )
+{
+ return (Sem_Control *) _sem;
+}
+
+static inline Thread_Control *_Sem_Queue_acquire_critical(
+ Sem_Control *sem,
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_Control *executing;
+
+ executing = _Thread_Executing;
+ _Thread_queue_Queue_acquire_critical(
+ &sem->Queue.Queue,
+ &executing->Potpourri_stats,
+ &queue_context->Lock_context.Lock_context
+ );
+
+ return executing;
+}
+
+static inline void _Sem_Queue_release(
+ Sem_Control *sem,
+ ISR_Level level,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Queue_release_critical(
+ &sem->Queue.Queue,
+ &queue_context->Lock_context.Lock_context
+ );
+ _ISR_Local_enable( level );
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SEMAPHOREIMPL_H */
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index da231541b0..32356e3c4a 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -288,6 +288,10 @@ $(PROJECT_INCLUDE)/rtems/score/schedulersmpimpl.h: include/rtems/score/scheduler
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulersmpimpl.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulersmpimpl.h
+$(PROJECT_INCLUDE)/rtems/score/semaphoreimpl.h: include/rtems/score/semaphoreimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/semaphoreimpl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/semaphoreimpl.h
+
$(PROJECT_INCLUDE)/rtems/score/smp.h: include/rtems/score/smp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/smp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/smp.h
diff --git a/cpukit/score/src/semaphore.c b/cpukit/score/src/semaphore.c
index 28a2f0a76d..e670367e86 100644
--- a/cpukit/score/src/semaphore.c
+++ b/cpukit/score/src/semaphore.c
@@ -16,92 +16,45 @@
#include "config.h"
#endif
-#include <sys/lock.h>
+#include <rtems/score/semaphoreimpl.h>
+#include <rtems/score/statesimpl.h>
#include <limits.h>
-#include <rtems/score/assert.h>
-#include <rtems/score/threadimpl.h>
-#include <rtems/score/threadqimpl.h>
-
-#define SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_priority
-
-typedef struct {
- Thread_queue_Syslock_queue Queue;
- unsigned int count;
-} Semaphore_Control;
-
RTEMS_STATIC_ASSERT(
- offsetof( Semaphore_Control, Queue )
+ offsetof( Sem_Control, Queue )
== offsetof( struct _Semaphore_Control, _Queue ),
SEMAPHORE_CONTROL_QUEUE
);
RTEMS_STATIC_ASSERT(
- offsetof( Semaphore_Control, count )
+ offsetof( Sem_Control, count )
== offsetof( struct _Semaphore_Control, _count ),
SEMAPHORE_CONTROL_COUNT
);
RTEMS_STATIC_ASSERT(
- sizeof( Semaphore_Control ) == sizeof( struct _Semaphore_Control ),
+ sizeof( Sem_Control ) == sizeof( struct _Semaphore_Control ),
SEMAPHORE_CONTROL_SIZE
);
-static Semaphore_Control *_Semaphore_Get(
- struct _Semaphore_Control *_sem
-)
-{
- return (Semaphore_Control *) _sem;
-}
-
-static Thread_Control *_Semaphore_Queue_acquire_critical(
- Semaphore_Control *sem,
- Thread_queue_Context *queue_context
-)
-{
- Thread_Control *executing;
-
- executing = _Thread_Executing;
- _Thread_queue_Queue_acquire_critical(
- &sem->Queue.Queue,
- &executing->Potpourri_stats,
- &queue_context->Lock_context.Lock_context
- );
-
- return executing;
-}
-
-static void _Semaphore_Queue_release(
- Semaphore_Control *sem,
- ISR_Level level,
- Thread_queue_Context *queue_context
-)
-{
- _Thread_queue_Queue_release_critical(
- &sem->Queue.Queue,
- &queue_context->Lock_context.Lock_context
- );
- _ISR_Local_enable( level );
-}
-
void _Semaphore_Wait( struct _Semaphore_Control *_sem )
{
- Semaphore_Control *sem ;
+ Sem_Control *sem;
ISR_Level level;
Thread_queue_Context queue_context;
Thread_Control *executing;
unsigned int count;
- sem = _Semaphore_Get( _sem );
+ sem = _Sem_Get( _sem );
_Thread_queue_Context_initialize( &queue_context );
_Thread_queue_Context_ISR_disable( &queue_context, level );
- executing = _Semaphore_Queue_acquire_critical( sem, &queue_context );
+ executing = _Sem_Queue_acquire_critical( sem, &queue_context );
count = sem->count;
if ( __predict_true( count > 0 ) ) {
sem->count = count - 1;
- _Semaphore_Queue_release( sem, level, &queue_context );
+ _Sem_Queue_release( sem, level, &queue_context );
} else {
_Thread_queue_Context_set_thread_state(
&queue_context,
@@ -121,21 +74,21 @@ void _Semaphore_Wait( struct _Semaphore_Control *_sem )
void _Semaphore_Post( struct _Semaphore_Control *_sem )
{
- Semaphore_Control *sem;
+ Sem_Control *sem;
ISR_Level level;
Thread_queue_Context queue_context;
Thread_queue_Heads *heads;
- sem = _Semaphore_Get( _sem );
+ sem = _Sem_Get( _sem );
_Thread_queue_Context_initialize( &queue_context );
_Thread_queue_Context_ISR_disable( &queue_context, level );
- _Semaphore_Queue_acquire_critical( sem, &queue_context );
+ _Sem_Queue_acquire_critical( sem, &queue_context );
heads = sem->Queue.Queue.heads;
if ( __predict_true( heads == NULL ) ) {
_Assert( sem->count < UINT_MAX );
++sem->count;
- _Semaphore_Queue_release( sem, level, &queue_context );
+ _Sem_Queue_release( sem, level, &queue_context );
} else {
const Thread_queue_Operations *operations;
Thread_Control *first;