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/score | |
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/score')
-rw-r--r-- | cpukit/score/Makefile.am | 1 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/semaphoreimpl.h | 73 | ||||
-rw-r--r-- | cpukit/score/preinstall.am | 4 | ||||
-rw-r--r-- | cpukit/score/src/semaphore.c | 73 |
4 files changed, 91 insertions, 60 deletions
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; |