diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-09-21 15:42:45 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-10-05 14:29:02 +0200 |
commit | 89fc9345dea5c675f8d93546fa3c723918d3279a (patch) | |
tree | 89c32d64f375e1a9bf9d3725b1256aeb7ca46221 /cpukit/score | |
parent | posix: Implement self-contained POSIX barriers (diff) | |
download | rtems-89fc9345dea5c675f8d93546fa3c723918d3279a.tar.bz2 |
posix: Implement self-contained POSIX rwlocks
POSIX rwlocks are now available in all configurations and no longer
depend on --enable-posix.
Update #2514.
Update #3115.
Diffstat (limited to 'cpukit/score')
-rw-r--r-- | cpukit/score/Makefile.am | 8 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/corerwlock.h | 77 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/corerwlockimpl.h | 68 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/objectimpl.h | 1 | ||||
-rw-r--r-- | cpukit/score/include/rtems/sysinit.h | 1 | ||||
-rw-r--r-- | cpukit/score/preinstall.am | 13 | ||||
-rw-r--r-- | cpukit/score/src/corerwlock.c | 3 | ||||
-rw-r--r-- | cpukit/score/src/corerwlockobtainread.c | 17 | ||||
-rw-r--r-- | cpukit/score/src/corerwlockobtainwrite.c | 7 | ||||
-rw-r--r-- | cpukit/score/src/corerwlockrelease.c | 20 |
10 files changed, 82 insertions, 133 deletions
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 03a15e3b09..86af199ec3 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -38,6 +38,7 @@ include_rtems_score_HEADERS += include/rtems/score/coremsg.h include_rtems_score_HEADERS += include/rtems/score/coremsgimpl.h include_rtems_score_HEADERS += include/rtems/score/coremutex.h include_rtems_score_HEADERS += include/rtems/score/coremuteximpl.h +include_rtems_score_HEADERS += include/rtems/score/corerwlockimpl.h include_rtems_score_HEADERS += include/rtems/score/coresem.h include_rtems_score_HEADERS += include/rtems/score/coresemimpl.h include_rtems_score_HEADERS += include/rtems/score/cpuset.h @@ -112,11 +113,6 @@ include_rtems_score_HEADERS += include/rtems/score/wkspace.h include_rtems_score_HEADERS += include/rtems/score/cpuopts.h include_rtems_score_HEADERS += include/rtems/score/basedefs.h -if HAS_PTHREADS -include_rtems_score_HEADERS += include/rtems/score/corerwlock.h -include_rtems_score_HEADERS += include/rtems/score/corerwlockimpl.h -endif - if HAS_MP # We only build multiprocessing related files if HAS_MP was defined include_rtems_score_HEADERS += include/rtems/score/mpci.h @@ -189,10 +185,8 @@ libscore_a_SOURCES += src/percpu.c libscore_a_SOURCES += src/percpuasm.c ## CORE_RWLOCK_C_FILES -if HAS_PTHREADS libscore_a_SOURCES += src/corerwlock.c src/corerwlockobtainread.c \ src/corerwlockobtainwrite.c src/corerwlockrelease.c -endif ## CORE_SEMAPHORE_C_FILES libscore_a_SOURCES += src/coresem.c diff --git a/cpukit/score/include/rtems/score/corerwlock.h b/cpukit/score/include/rtems/score/corerwlock.h deleted file mode 100644 index 89c18c6c65..0000000000 --- a/cpukit/score/include/rtems/score/corerwlock.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file rtems/score/corerwlock.h - * - * @brief Constants and Structures Associated with the RWLock Handler - * - * This include file contains all the constants and structures associated - * with the RWLock Handler. - */ - -/* - * COPYRIGHT (c) 1989-2008. - * 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. - */ - -#ifndef _RTEMS_SCORE_CORERWLOCK_H -#define _RTEMS_SCORE_CORERWLOCK_H - -#include <rtems/score/threadq.h> - -/** - * @defgroup ScoreRWLock RWLock Handler - * - * @ingroup Score - * - * This handler encapsulates functionality which provides the foundation - * RWLock services used in all of the APIs supported by RTEMS. - */ -/**@{*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * RWLock State. - */ -typedef enum { - /** This indicates the the RWLock is not currently locked. - */ - CORE_RWLOCK_UNLOCKED, - /** This indicates the the RWLock is currently locked for reading. - */ - CORE_RWLOCK_LOCKED_FOR_READING, - /** This indicates the the RWLock is currently locked for reading. - */ - CORE_RWLOCK_LOCKED_FOR_WRITING -} CORE_RWLock_States; - -/** - * The following defines the control block used to manage each - * RWLock. - */ -typedef struct { - /** This field is the Waiting Queue used to manage the set of tasks - * which are blocked waiting for the RWLock to be released. - */ - Thread_queue_Control Wait_queue; - /** This element is the current state of the RWLock. - */ - CORE_RWLock_States current_state; - /** This element contains the current number of thread waiting for this - * RWLock to be released. */ - uint32_t number_of_readers; -} CORE_RWLock_Control; - -/**@}*/ - -#ifdef __cplusplus -} -#endif - -#endif -/* end of include file */ diff --git a/cpukit/score/include/rtems/score/corerwlockimpl.h b/cpukit/score/include/rtems/score/corerwlockimpl.h index 330d9acc55..942e8c8d75 100644 --- a/cpukit/score/include/rtems/score/corerwlockimpl.h +++ b/cpukit/score/include/rtems/score/corerwlockimpl.h @@ -19,10 +19,10 @@ #ifndef _RTEMS_SCORE_CORERWLOCKIMPL_H #define _RTEMS_SCORE_CORERWLOCKIMPL_H -#include <rtems/score/corerwlock.h> +#include <rtems/score/percpu.h> +#include <rtems/score/status.h> #include <rtems/score/thread.h> #include <rtems/score/threadqimpl.h> -#include <rtems/score/status.h> #include <rtems/score/watchdog.h> #ifdef __cplusplus @@ -49,6 +49,40 @@ extern "C" { #define CORE_RWLOCK_THREAD_WAITING_FOR_WRITE 1 /** + * RWLock State. + */ +typedef enum { + /** This indicates the the RWLock is not currently locked. + */ + CORE_RWLOCK_UNLOCKED, + /** This indicates the the RWLock is currently locked for reading. + */ + CORE_RWLOCK_LOCKED_FOR_READING, + /** This indicates the the RWLock is currently locked for reading. + */ + CORE_RWLOCK_LOCKED_FOR_WRITING +} CORE_RWLock_States; + +/** + * The following defines the control block used to manage each + * RWLock. + */ +typedef struct { + /** This field is the Waiting Queue used to manage the set of tasks + * which are blocked waiting for the RWLock to be released. + */ + Thread_queue_Syslock_queue Queue; + + /** This element is the current state of the RWLock. + */ + CORE_RWLock_States current_state; + + /** This element contains the current number of thread waiting for this + * RWLock to be released. */ + unsigned int number_of_readers; +} CORE_RWLock_Control; + +/** * @brief Initialize a RWlock. * * This routine initializes the RWLock based on the parameters passed. @@ -63,15 +97,27 @@ RTEMS_INLINE_ROUTINE void _CORE_RWLock_Destroy( CORE_RWLock_Control *the_rwlock ) { - _Thread_queue_Destroy( &the_rwlock->Wait_queue ); + (void) the_rwlock; } -RTEMS_INLINE_ROUTINE void _CORE_RWLock_Acquire_critical( +RTEMS_INLINE_ROUTINE Thread_Control *_CORE_RWLock_Acquire( CORE_RWLock_Control *the_rwlock, Thread_queue_Context *queue_context ) { - _Thread_queue_Acquire_critical( &the_rwlock->Wait_queue, queue_context ); + ISR_Level level; + Thread_Control *executing; + + _Thread_queue_Context_ISR_disable( queue_context, level ); + _Thread_queue_Context_set_ISR_level( queue_context, level ); + executing = _Thread_Executing; + _Thread_queue_Queue_acquire_critical( + &the_rwlock->Queue.Queue, + &executing->Potpourri_stats, + &queue_context->Lock_context.Lock_context + ); + + return executing; } RTEMS_INLINE_ROUTINE void _CORE_RWLock_Release( @@ -79,7 +125,10 @@ RTEMS_INLINE_ROUTINE void _CORE_RWLock_Release( Thread_queue_Context *queue_context ) { - _Thread_queue_Release( &the_rwlock->Wait_queue, queue_context ); + _Thread_queue_Queue_release( + &the_rwlock->Queue.Queue, + &queue_context->Lock_context.Lock_context + ); } /** @@ -93,7 +142,6 @@ RTEMS_INLINE_ROUTINE void _CORE_RWLock_Release( Status_Control _CORE_RWLock_Seize_for_reading( CORE_RWLock_Control *the_rwlock, - Thread_Control *executing, bool wait, Thread_queue_Context *queue_context ); @@ -108,7 +156,6 @@ Status_Control _CORE_RWLock_Seize_for_reading( */ Status_Control _CORE_RWLock_Seize_for_writing( CORE_RWLock_Control *the_rwlock, - Thread_Control *executing, bool wait, Thread_queue_Context *queue_context ); @@ -123,10 +170,7 @@ Status_Control _CORE_RWLock_Seize_for_writing( * * @retval Status is returned to indicate successful or failure. */ -Status_Control _CORE_RWLock_Surrender( - CORE_RWLock_Control *the_rwlock, - Thread_queue_Context *queue_context -); +Status_Control _CORE_RWLock_Surrender( CORE_RWLock_Control *the_rwlock ); /** @} */ diff --git a/cpukit/score/include/rtems/score/objectimpl.h b/cpukit/score/include/rtems/score/objectimpl.h index e68035d338..f8e7ddd284 100644 --- a/cpukit/score/include/rtems/score/objectimpl.h +++ b/cpukit/score/include/rtems/score/objectimpl.h @@ -91,7 +91,6 @@ typedef enum { OBJECTS_POSIX_SEMAPHORES = 7, OBJECTS_POSIX_CONDITION_VARIABLES = 8, OBJECTS_POSIX_TIMERS = 9, - OBJECTS_POSIX_RWLOCKS = 11, OBJECTS_POSIX_SHMS = 12 } Objects_POSIX_API; diff --git a/cpukit/score/include/rtems/sysinit.h b/cpukit/score/include/rtems/sysinit.h index 29ad24dc2f..09b82e6836 100644 --- a/cpukit/score/include/rtems/sysinit.h +++ b/cpukit/score/include/rtems/sysinit.h @@ -52,7 +52,6 @@ extern "C" { #define RTEMS_SYSINIT_POSIX_MESSAGE_QUEUE 000364 #define RTEMS_SYSINIT_POSIX_SEMAPHORE 000365 #define RTEMS_SYSINIT_POSIX_TIMER 000366 -#define RTEMS_SYSINIT_POSIX_RWLOCK 000368 #define RTEMS_SYSINIT_POSIX_SHM 000369 #define RTEMS_SYSINIT_POSIX_KEYS 00036a #define RTEMS_SYSINIT_POSIX_CLEANUP 00036b diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am index 32356e3c4a..0e05b5548e 100644 --- a/cpukit/score/preinstall.am +++ b/cpukit/score/preinstall.am @@ -120,6 +120,10 @@ $(PROJECT_INCLUDE)/rtems/score/coremuteximpl.h: include/rtems/score/coremuteximp $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coremuteximpl.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coremuteximpl.h +$(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h: include/rtems/score/corerwlockimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h + $(PROJECT_INCLUDE)/rtems/score/coresem.h: include/rtems/score/coresem.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coresem.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coresem.h @@ -412,15 +416,6 @@ $(PROJECT_INCLUDE)/rtems/score/basedefs.h: include/rtems/score/basedefs.h $(PROJ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/basedefs.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/basedefs.h -if HAS_PTHREADS -$(PROJECT_INCLUDE)/rtems/score/corerwlock.h: include/rtems/score/corerwlock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/corerwlock.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/corerwlock.h - -$(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h: include/rtems/score/corerwlockimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/corerwlockimpl.h -endif if HAS_MP $(PROJECT_INCLUDE)/rtems/score/mpci.h: include/rtems/score/mpci.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/mpci.h diff --git a/cpukit/score/src/corerwlock.c b/cpukit/score/src/corerwlock.c index 51ae2c70df..9ebb796ac4 100644 --- a/cpukit/score/src/corerwlock.c +++ b/cpukit/score/src/corerwlock.c @@ -27,6 +27,5 @@ void _CORE_RWLock_Initialize( { the_rwlock->number_of_readers = 0; the_rwlock->current_state = CORE_RWLOCK_UNLOCKED; - - _Thread_queue_Object_initialize( &the_rwlock->Wait_queue ); + _Thread_queue_Queue_initialize( &the_rwlock->Queue.Queue, NULL ); } diff --git a/cpukit/score/src/corerwlockobtainread.c b/cpukit/score/src/corerwlockobtainread.c index 641945635f..d0bd7b09ce 100644 --- a/cpukit/score/src/corerwlockobtainread.c +++ b/cpukit/score/src/corerwlockobtainread.c @@ -26,18 +26,19 @@ Status_Control _CORE_RWLock_Seize_for_reading( CORE_RWLock_Control *the_rwlock, - Thread_Control *executing, bool wait, Thread_queue_Context *queue_context ) { + Thread_Control *executing; + /* * If unlocked, then OK to read. * If locked for reading and no waiters, then OK to read. * If any thread is waiting, then we wait. */ - _CORE_RWLock_Acquire_critical( the_rwlock, queue_context ); + executing = _CORE_RWLock_Acquire( the_rwlock, queue_context ); switch ( the_rwlock->current_state ) { case CORE_RWLOCK_UNLOCKED: @@ -46,19 +47,13 @@ Status_Control _CORE_RWLock_Seize_for_reading( _CORE_RWLock_Release( the_rwlock, queue_context ); return STATUS_SUCCESSFUL; - case CORE_RWLOCK_LOCKED_FOR_READING: { - Thread_Control *waiter; - waiter = _Thread_queue_First_locked( - &the_rwlock->Wait_queue, - CORE_RWLOCK_TQ_OPERATIONS - ); - if ( !waiter ) { + case CORE_RWLOCK_LOCKED_FOR_READING: + if ( _Thread_queue_Is_empty( &the_rwlock->Queue.Queue ) ) { the_rwlock->number_of_readers += 1; _CORE_RWLock_Release( the_rwlock, queue_context ); return STATUS_SUCCESSFUL; } break; - } case CORE_RWLOCK_LOCKED_FOR_WRITING: break; } @@ -84,7 +79,7 @@ Status_Control _CORE_RWLock_Seize_for_reading( ); _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Enqueue( - &the_rwlock->Wait_queue.Queue, + &the_rwlock->Queue.Queue, CORE_RWLOCK_TQ_OPERATIONS, executing, queue_context diff --git a/cpukit/score/src/corerwlockobtainwrite.c b/cpukit/score/src/corerwlockobtainwrite.c index 7f636daa99..6859163f1f 100644 --- a/cpukit/score/src/corerwlockobtainwrite.c +++ b/cpukit/score/src/corerwlockobtainwrite.c @@ -26,11 +26,12 @@ Status_Control _CORE_RWLock_Seize_for_writing( CORE_RWLock_Control *the_rwlock, - Thread_Control *executing, bool wait, Thread_queue_Context *queue_context ) { + Thread_Control *executing; + /* * If unlocked, then OK to read. * Otherwise, we have to block. @@ -38,7 +39,7 @@ Status_Control _CORE_RWLock_Seize_for_writing( * If any thread is waiting, then we wait. */ - _CORE_RWLock_Acquire_critical( the_rwlock, queue_context ); + executing = _CORE_RWLock_Acquire( the_rwlock, queue_context ); switch ( the_rwlock->current_state ) { case CORE_RWLOCK_UNLOCKED: @@ -72,7 +73,7 @@ Status_Control _CORE_RWLock_Seize_for_writing( ); _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Enqueue( - &the_rwlock->Wait_queue.Queue, + &the_rwlock->Queue.Queue, CORE_RWLOCK_TQ_OPERATIONS, executing, queue_context diff --git a/cpukit/score/src/corerwlockrelease.c b/cpukit/score/src/corerwlockrelease.c index 71aa12a190..772d16dc25 100644 --- a/cpukit/score/src/corerwlockrelease.c +++ b/cpukit/score/src/corerwlockrelease.c @@ -45,7 +45,7 @@ static Thread_Control *_CORE_RWLock_Flush_filter( the_rwlock = RTEMS_CONTAINER_OF( queue, CORE_RWLock_Control, - Wait_queue.Queue + Queue.Queue ); switch ( the_rwlock->current_state ) { @@ -73,11 +73,10 @@ static Thread_Control *_CORE_RWLock_Flush_filter( return the_thread; } -Status_Control _CORE_RWLock_Surrender( - CORE_RWLock_Control *the_rwlock, - Thread_queue_Context *queue_context -) +Status_Control _CORE_RWLock_Surrender( CORE_RWLock_Control *the_rwlock ) { + Thread_queue_Context queue_context; + /* * If unlocked, then OK to read. * Otherwise, we have to block. @@ -85,11 +84,12 @@ Status_Control _CORE_RWLock_Surrender( * If any thread is waiting, then we wait. */ - _CORE_RWLock_Acquire_critical( the_rwlock, queue_context ); + _Thread_queue_Context_initialize( &queue_context ); + _CORE_RWLock_Acquire( the_rwlock, &queue_context ); if ( the_rwlock->current_state == CORE_RWLOCK_UNLOCKED){ /* This is an error at the caller site */ - _CORE_RWLock_Release( the_rwlock, queue_context ); + _CORE_RWLock_Release( the_rwlock, &queue_context ); return STATUS_SUCCESSFUL; } @@ -98,7 +98,7 @@ Status_Control _CORE_RWLock_Surrender( if ( the_rwlock->number_of_readers != 0 ) { /* must be unlocked again */ - _CORE_RWLock_Release( the_rwlock, queue_context ); + _CORE_RWLock_Release( the_rwlock, &queue_context ); return STATUS_SUCCESSFUL; } } @@ -116,10 +116,10 @@ Status_Control _CORE_RWLock_Surrender( the_rwlock->current_state = CORE_RWLOCK_UNLOCKED; _Thread_queue_Flush_critical( - &the_rwlock->Wait_queue.Queue, + &the_rwlock->Queue.Queue, CORE_RWLOCK_TQ_OPERATIONS, _CORE_RWLock_Flush_filter, - queue_context + &queue_context ); return STATUS_SUCCESSFUL; } |