diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-11-16 14:50:09 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-11-23 12:52:06 +0100 |
commit | c42be504c92d76d2e06d0fc8ebd05fc913376d2d (patch) | |
tree | 259f8a712a6139f427888647955bc3c95480877e /cpukit/posix | |
parent | score: Add RTEMS_ALIAS() (diff) | |
download | rtems-c42be504c92d76d2e06d0fc8ebd05fc913376d2d.tar.bz2 |
posix: Add self-contained pthread spinlock
Turn pthread_spinlock_t into a self-contained object. On uni-processor
configurations, interrupts are disabled in the lock/trylock operations
and the previous interrupt status is restored in the corresponding
unlock operations. On SMP configurations, a ticket lock is a acquired
and released in addition.
The self-contained pthread_spinlock_t object is defined by Newlib in
<sys/_pthreadtypes.h>.
typedef struct {
struct _Ticket_lock_Control _lock;
__uint32_t _interrupt_state;
} pthread_spinlock_t;
This implementation is simple and efficient. However, this test case of
the Linux Test Project would fail due to call of printf() and sleep()
during spin lock ownership:
https://github.com/linux-test-project/ltp/blob/master/testcases/open_posix_testsuite/conformance/interfaces/pthread_spin_lock/1-2.c
There is only limited support for profiling on SMP configurations.
Delete CORE spinlock implementation.
Update #2674.
Diffstat (limited to '')
-rw-r--r-- | cpukit/posix/Makefile.am | 14 | ||||
-rw-r--r-- | cpukit/posix/include/rtems/posix/config.h | 6 | ||||
-rw-r--r-- | cpukit/posix/include/rtems/posix/spinlock.h | 63 | ||||
-rw-r--r-- | cpukit/posix/include/rtems/posix/spinlockimpl.h | 81 | ||||
-rw-r--r-- | cpukit/posix/preinstall.am | 12 | ||||
-rw-r--r-- | cpukit/posix/src/pspin.c | 51 | ||||
-rw-r--r-- | cpukit/posix/src/pspindestroy.c | 30 | ||||
-rw-r--r-- | cpukit/posix/src/pspininit.c | 52 | ||||
-rw-r--r-- | cpukit/posix/src/pspinlock.c | 96 | ||||
-rw-r--r-- | cpukit/posix/src/pspintrylock.c | 42 | ||||
-rw-r--r-- | cpukit/posix/src/pspinunlock.c | 36 |
11 files changed, 171 insertions, 312 deletions
diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am index 5bf11c7713..d9a3437b13 100644 --- a/cpukit/posix/Makefile.am +++ b/cpukit/posix/Makefile.am @@ -21,6 +21,7 @@ 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/spinlockimpl.h if HAS_PTHREADS # include @@ -52,8 +53,6 @@ include_rtems_posix_HEADERS += include/rtems/posix/barrier.h include_rtems_posix_HEADERS += include/rtems/posix/barrierimpl.h include_rtems_posix_HEADERS += include/rtems/posix/rwlock.h include_rtems_posix_HEADERS += include/rtems/posix/rwlockimpl.h -include_rtems_posix_HEADERS += include/rtems/posix/spinlock.h -include_rtems_posix_HEADERS += include/rtems/posix/spinlockimpl.h ## src libposix_a_SOURCES += src/aio_cancel.c src/aio_error.c src/aio_fsync.c \ @@ -168,6 +167,12 @@ libposix_a_SOURCES += src/sigaddset.c src/sigdelset.c src/sigfillset.c \ libposix_a_SOURCES += src/sigprocmask.c +## SPINLOCK_C_FILES +libposix_a_SOURCES += src/pspindestroy.c +libposix_a_SOURCES += src/pspininit.c +libposix_a_SOURCES += src/pspinlock.c +libposix_a_SOURCES += src/pspinunlock.c + if HAS_PTHREADS libposix_a_SOURCES += src/sigpending.c \ src/sigqueue.c src/sigsuspend.c src/sigtimedwait.c \ @@ -188,11 +193,6 @@ libposix_a_SOURCES += src/semaphore.c src/semaphorecreatesupp.c \ src/semopen.c src/sempost.c src/semtimedwait.c src/semtrywait.c \ src/semunlink.c src/semwait.c -## SPINLOCK_C_FILES -libposix_a_SOURCES += src/pspin.c src/pspindestroy.c src/pspininit.c \ - src/pspinlock.c src/pspintrylock.c \ - src/pspinunlock.c - ## TIME_C_FILES libposix_a_SOURCES += src/adjtime.c src/clockgetcpuclockid.c diff --git a/cpukit/posix/include/rtems/posix/config.h b/cpukit/posix/include/rtems/posix/config.h index 636f1e7d79..11c73c2b2f 100644 --- a/cpukit/posix/include/rtems/posix/config.h +++ b/cpukit/posix/include/rtems/posix/config.h @@ -111,12 +111,6 @@ typedef struct { uint32_t maximum_rwlocks; /** - * This field contains the maximum number of POSIX API - * spinlocks which are configured for this application. - */ - uint32_t maximum_spinlocks; - - /** * This field contains the number of POSIX API Initialization * threads listed in @a User_initialization_thread_table. */ diff --git a/cpukit/posix/include/rtems/posix/spinlock.h b/cpukit/posix/include/rtems/posix/spinlock.h deleted file mode 100644 index 8da451ce22..0000000000 --- a/cpukit/posix/include/rtems/posix/spinlock.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file - * - * @brief POSIX Spinlock Support - * - * This include file contains all the constants and structures associated - * with the POSIX Spinlock Manager. - * - * Directives provided are: - * - * - create a spinlock - * - delete a spinlock - * - wait for a spinlock - */ - -/* - * COPYRIGHT (c) 1989-2011. - * 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_POSIX_SPINLOCK_H -#define _RTEMS_POSIX_SPINLOCK_H - -#include <rtems/score/object.h> -#include <rtems/score/corespinlock.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup POSIX_SPINLOCK POSIX Spinlock Support - * - * @ingroup POSIXAPI - * - * @brief Constants and Structures Associated with the POSIX Spinlock Manager - * - */ -/**@{**/ - -/** - * This type defines the control block used to manage each spinlock. - */ - -typedef struct { - /** This is used to manage a spinlock as an object. */ - Objects_Control Object; - /** This is used to implement the spinlock. */ - CORE_spinlock_Control Spinlock; -} POSIX_Spinlock_Control; - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif -/* end of include file */ diff --git a/cpukit/posix/include/rtems/posix/spinlockimpl.h b/cpukit/posix/include/rtems/posix/spinlockimpl.h index f1b5639bd1..36ef6677a0 100644 --- a/cpukit/posix/include/rtems/posix/spinlockimpl.h +++ b/cpukit/posix/include/rtems/posix/spinlockimpl.h @@ -11,6 +11,8 @@ * COPYRIGHT (c) 1989-2011. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH + * * 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. @@ -19,62 +21,55 @@ #ifndef _RTEMS_POSIX_SPINLOCKIMPL_H #define _RTEMS_POSIX_SPINLOCKIMPL_H -#include <rtems/posix/spinlock.h> -#include <rtems/score/corespinlockimpl.h> -#include <rtems/score/objectimpl.h> - #include <pthread.h> +#include <rtems/score/isrlevel.h> + +#if defined(RTEMS_SMP) +#include <rtems/score/percpu.h> +#include <rtems/score/smplockticket.h> +#endif + #ifdef __cplusplus extern "C" { #endif -/** - * The following defines the information control block used to manage - * this class of objects. - */ +#if SIZEOF_PTHREAD_SPINLOCK_T > 4 +#define POSIX_SPINLOCKS_ARE_SELF_CONTAINED +#endif -extern Objects_Information _POSIX_Spinlock_Information; +typedef struct { +#if defined(RTEMS_SMP) + SMP_ticket_lock_Control Lock; +#else + unsigned int reserved[ 2 ]; +#endif + ISR_Level interrupt_state; +} POSIX_Spinlock_Control; -/** - * @brief Allocate a spinlock control block. - * - * This function allocates a spinlock control block from - * the inactive chain of free spinlock control blocks. - */ -RTEMS_INLINE_ROUTINE POSIX_Spinlock_Control *_POSIX_Spinlock_Allocate( void ) -{ - return (POSIX_Spinlock_Control *) - _Objects_Allocate( &_POSIX_Spinlock_Information ); -} +#if !defined(POSIX_SPINLOCKS_ARE_SELF_CONTAINED) +#if defined(RTEMS_SMP) +extern POSIX_Spinlock_Control _POSIX_Spinlock_Global; -/** - * @brief Free a spinlock control block. - * - * This routine frees a spinlock control block to the - * inactive chain of free spinlock control blocks. - */ -RTEMS_INLINE_ROUTINE void _POSIX_Spinlock_Free ( - POSIX_Spinlock_Control *the_spinlock -) -{ - _Objects_Free( &_POSIX_Spinlock_Information, &the_spinlock->Object ); -} +extern uint32_t _POSIX_Spinlock_Owner; +#endif + +extern int _POSIX_Spinlock_Nest_level; +#endif RTEMS_INLINE_ROUTINE POSIX_Spinlock_Control *_POSIX_Spinlock_Get( - pthread_spinlock_t *spinlock, - ISR_lock_Context *lock_context + pthread_spinlock_t *lock ) { - if ( spinlock == NULL ) { - return NULL; - } - - return (POSIX_Spinlock_Control *) _Objects_Get( - *spinlock, - lock_context, - &_POSIX_Spinlock_Information - ); +#if defined(POSIX_SPINLOCKS_ARE_SELF_CONTAINED) + return (POSIX_Spinlock_Control *) lock; +#elif defined(RTEMS_SMP) + (void) lock; + return &_POSIX_Spinlock_Global; +#else + (void) lock; + return NULL; +#endif } #ifdef __cplusplus diff --git a/cpukit/posix/preinstall.am b/cpukit/posix/preinstall.am index 1d035e7425..4f1b220fe1 100644 --- a/cpukit/posix/preinstall.am +++ b/cpukit/posix/preinstall.am @@ -47,6 +47,10 @@ $(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/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 + if HAS_PTHREADS $(PROJECT_INCLUDE)/aio.h: include/aio.h $(PROJECT_INCLUDE)/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/aio.h @@ -144,14 +148,6 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/rwlock.h $(PROJECT_INCLUDE)/rtems/posix/rwlockimpl.h: include/rtems/posix/rwlockimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/rwlockimpl.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/rwlockimpl.h - -$(PROJECT_INCLUDE)/rtems/posix/spinlock.h: include/rtems/posix/spinlock.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/spinlock.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/spinlock.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 endif if HAS_PTHREADS endif diff --git a/cpukit/posix/src/pspin.c b/cpukit/posix/src/pspin.c deleted file mode 100644 index 6c466bcab5..0000000000 --- a/cpukit/posix/src/pspin.c +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file - * - * This file contains the initialization of the POSIX Spinlock Manager. - */ - -/* - * COPYRIGHT (c) 1989-2013. - * 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 <limits.h> - -#include <rtems/system.h> -#include <rtems/config.h> -#include <rtems/sysinit.h> -#include <rtems/posix/spinlockimpl.h> - -Objects_Information _POSIX_Spinlock_Information; - -/** - * @brief _POSIX_Spinlock_Manager_initialization - */ -static void _POSIX_Spinlock_Manager_initialization(void) -{ - _Objects_Initialize_information( - &_POSIX_Spinlock_Information, /* object information table */ - OBJECTS_POSIX_API, /* object API */ - OBJECTS_POSIX_SPINLOCKS, /* object class */ - Configuration_POSIX_API.maximum_spinlocks, - /* maximum objects of this class */ - sizeof( POSIX_Spinlock_Control ),/* size of this object's control block */ - true, /* true if the name is a string */ - _POSIX_PATH_MAX, /* maximum length of each object's name */ - NULL /* Proxy extraction support callout */ - ); -} - -RTEMS_SYSINIT_ITEM( - _POSIX_Spinlock_Manager_initialization, - RTEMS_SYSINIT_POSIX_SPINLOCK, - RTEMS_SYSINIT_ORDER_MIDDLE -); diff --git a/cpukit/posix/src/pspindestroy.c b/cpukit/posix/src/pspindestroy.c index 42a6e76806..f5de88f04b 100644 --- a/cpukit/posix/src/pspindestroy.c +++ b/cpukit/posix/src/pspindestroy.c @@ -9,6 +9,8 @@ * COPYRIGHT (c) 1989-2007. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH + * * 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. @@ -20,33 +22,13 @@ #include <rtems/posix/spinlockimpl.h> -#include <errno.h> - int pthread_spin_destroy( pthread_spinlock_t *spinlock ) { +#if defined(RTEMS_SMP) && defined(POSIX_SPINLOCKS_ARE_SELF_CONTAINED) POSIX_Spinlock_Control *the_spinlock; - ISR_lock_Context lock_context; - - _Objects_Allocator_lock(); - - the_spinlock = _POSIX_Spinlock_Get( spinlock, &lock_context ); - if ( the_spinlock == NULL ) { - _Objects_Allocator_unlock(); - return EINVAL; - } - _CORE_spinlock_Acquire_critical( &the_spinlock->Spinlock, &lock_context ); - - if ( _CORE_spinlock_Is_busy( &the_spinlock->Spinlock ) ) { - _CORE_spinlock_Release( &the_spinlock->Spinlock, &lock_context ); - _Objects_Allocator_unlock(); - return EBUSY; - } - - _CORE_spinlock_Release( &the_spinlock->Spinlock, &lock_context ); - - _Objects_Close( &_POSIX_Spinlock_Information, &the_spinlock->Object ); - _POSIX_Spinlock_Free( the_spinlock ); - _Objects_Allocator_unlock(); + the_spinlock = _POSIX_Spinlock_Get( spinlock ); + _SMP_ticket_lock_Destroy( &the_spinlock->Lock ); +#endif return 0; } diff --git a/cpukit/posix/src/pspininit.c b/cpukit/posix/src/pspininit.c index bc131e2e81..313633a11e 100644 --- a/cpukit/posix/src/pspininit.c +++ b/cpukit/posix/src/pspininit.c @@ -11,6 +11,8 @@ * COPYRIGHT (c) 1989-2006. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH + * * 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. @@ -20,58 +22,18 @@ #include "config.h" #endif -#include <pthread.h> -#include <errno.h> - -#include <rtems/system.h> #include <rtems/posix/spinlockimpl.h> -/* - * pthread_spinlock_init - * - * This directive creates a spinlock. A spinlock id is returned. - * - * Input parameters: - * spinlock - pointer to spinlock id - * pshared - is this spinlock shared between processes - * - * Output parameters: - * spinlock - spinlock id - * 0 - if successful - * error code - if unsuccessful - */ - int pthread_spin_init( pthread_spinlock_t *spinlock, int pshared ) { - POSIX_Spinlock_Control *the_spinlock; +#if defined(RTEMS_SMP) && defined(POSIX_SPINLOCKS_ARE_SELF_CONTAINED) + POSIX_Spinlock_Control *the_spinlock; - if ( !spinlock ) - return EINVAL; - - switch ( pshared ) { - case PTHREAD_PROCESS_PRIVATE: /* only supported values */ - break; - case PTHREAD_PROCESS_SHARED: - default: - return EINVAL; - } - - the_spinlock = _POSIX_Spinlock_Allocate(); - - if ( !the_spinlock ) { - _Objects_Allocator_unlock(); - return EAGAIN; - } - - _CORE_spinlock_Initialize( &the_spinlock->Spinlock ); - - _Objects_Open_u32( &_POSIX_Spinlock_Information, &the_spinlock->Object, 0 ); - - *spinlock = the_spinlock->Object.id; - - _Objects_Allocator_unlock(); + the_spinlock = _POSIX_Spinlock_Get( spinlock ); + _SMP_ticket_lock_Initialize( &the_spinlock->Lock ); +#endif return 0; } diff --git a/cpukit/posix/src/pspinlock.c b/cpukit/posix/src/pspinlock.c index a2db911698..a9b04d8392 100644 --- a/cpukit/posix/src/pspinlock.c +++ b/cpukit/posix/src/pspinlock.c @@ -9,6 +9,8 @@ * COPYRIGHT (c) 1989-2007. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH + * * 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. @@ -19,24 +21,92 @@ #endif #include <rtems/posix/spinlockimpl.h> -#include <rtems/posix/posixapi.h> + +#if defined(POSIX_SPINLOCKS_ARE_SELF_CONTAINED) +RTEMS_STATIC_ASSERT( +#if defined(RTEMS_SMP) + offsetof( POSIX_Spinlock_Control, Lock.next_ticket ) +#else + offsetof( POSIX_Spinlock_Control, reserved[ 0 ] ) +#endif + == offsetof( pthread_spinlock_t, _Lock._next_ticket ), + POSIX_SPINLOCK_T_LOCK_NEXT_TICKET +); + +RTEMS_STATIC_ASSERT( +#if defined(RTEMS_SMP) + offsetof( POSIX_Spinlock_Control, Lock.now_serving ) +#else + offsetof( POSIX_Spinlock_Control, reserved[ 1 ] ) +#endif + == offsetof( pthread_spinlock_t, _Lock._now_serving ), + POSIX_SPINLOCK_T_LOCK_NOW_SERVING +); + +RTEMS_STATIC_ASSERT( + offsetof( POSIX_Spinlock_Control, interrupt_state ) + == offsetof( pthread_spinlock_t, _interrupt_state ), + POSIX_SPINLOCK_T_INTERRUPT_STATE +); + +RTEMS_STATIC_ASSERT( + sizeof( POSIX_Spinlock_Control ) == sizeof( pthread_spinlock_t ), + POSIX_SPINLOCK_T_SIZE +); +#else +#if defined(RTEMS_SMP) +POSIX_Spinlock_Control _POSIX_Spinlock_Global; + +uint32_t _POSIX_Spinlock_Owner = 0xffffffff; +#endif + +int _POSIX_Spinlock_Nest_level; +#endif int pthread_spin_lock( pthread_spinlock_t *spinlock ) { POSIX_Spinlock_Control *the_spinlock; - ISR_lock_Context lock_context; - Status_Control status; + ISR_Level level; +#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING) + Per_CPU_Control *cpu_self; +#endif - the_spinlock = _POSIX_Spinlock_Get( spinlock, &lock_context ); - if ( the_spinlock == NULL ) { - return EINVAL; + the_spinlock = _POSIX_Spinlock_Get( spinlock ); + _ISR_Local_disable( level ); +#if defined(POSIX_SPINLOCKS_ARE_SELF_CONTAINED) +#if defined(RTEMS_SMP) +#if defined(RTEMS_PROFILING) + /* The lock statistics are incorrect in case of nested pthread spinlocks */ + cpu_self = _Per_CPU_Get(); +#endif + _SMP_ticket_lock_Acquire( + &the_spinlock->Lock, + &cpu_self->Lock_stats, + &cpu_self->Lock_stats_context + ); +#endif + the_spinlock->interrupt_state = level; +#else +#if defined(RTEMS_SMP) + if ( _POSIX_Spinlock_Owner != _SMP_Get_current_processor() ) { +#if defined(RTEMS_PROFILING) + cpu_self = _Per_CPU_Get(); +#endif + _SMP_ticket_lock_Acquire( + &the_spinlock->Lock, + &cpu_self->Lock_stats, + &cpu_self->Lock_stats_context + ); + _POSIX_Spinlock_Owner = _SMP_Get_current_processor(); +#endif } - status = _CORE_spinlock_Seize( - &the_spinlock->Spinlock, - true, - 0, - &lock_context - ); - return _POSIX_Get_error( status ); + if ( ++_POSIX_Spinlock_Nest_level == 1) { + the_spinlock->interrupt_state = level; + } +#endif + return 0; } + +int pthread_spin_trylock( pthread_spinlock_t *spinlock ) + RTEMS_ALIAS( pthread_spin_lock ); diff --git a/cpukit/posix/src/pspintrylock.c b/cpukit/posix/src/pspintrylock.c deleted file mode 100644 index a8264aba97..0000000000 --- a/cpukit/posix/src/pspintrylock.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file - * - * @brief Wait at a Spinlock - * @ingroup POSIXAPI - */ - -/* - * COPYRIGHT (c) 1989-2007. - * 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 <rtems/posix/spinlockimpl.h> -#include <rtems/posix/posixapi.h> - -int pthread_spin_trylock( pthread_spinlock_t *spinlock ) -{ - POSIX_Spinlock_Control *the_spinlock; - ISR_lock_Context lock_context; - Status_Control status; - - the_spinlock = _POSIX_Spinlock_Get( spinlock, &lock_context ); - if ( the_spinlock == NULL ) { - return EINVAL; - } - - status = _CORE_spinlock_Seize( - &the_spinlock->Spinlock, - false, - 0, - &lock_context - ); - return _POSIX_Get_error( status ); -} diff --git a/cpukit/posix/src/pspinunlock.c b/cpukit/posix/src/pspinunlock.c index b92473d7c1..b508df7384 100644 --- a/cpukit/posix/src/pspinunlock.c +++ b/cpukit/posix/src/pspinunlock.c @@ -11,6 +11,8 @@ * COPYRIGHT (c) 1989-2007. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH + * * 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. @@ -21,19 +23,33 @@ #endif #include <rtems/posix/spinlockimpl.h> -#include <rtems/posix/posixapi.h> -int pthread_spin_unlock( pthread_spinlock_t *spinlock ) +int pthread_spin_unlock( pthread_spinlock_t *lock ) { POSIX_Spinlock_Control *the_spinlock; - ISR_lock_Context lock_context; - Status_Control status; + ISR_Level level; - the_spinlock = _POSIX_Spinlock_Get( spinlock, &lock_context ); - if ( the_spinlock == NULL ) { - return EINVAL; + the_spinlock = _POSIX_Spinlock_Get( lock ); + level = the_spinlock->interrupt_state; +#if defined(POSIX_SPINLOCKS_ARE_SELF_CONTAINED) +#if defined(RTEMS_SMP) + _SMP_ticket_lock_Release( + &the_spinlock->Lock, + &_Per_CPU_Get()->Lock_stats_context + ); +#endif + _ISR_Local_enable( level ); +#else + if ( --_POSIX_Spinlock_Nest_level == 0 ) { +#if defined(RTEMS_SMP) + _POSIX_Spinlock_Owner = 0xffffffff; + _SMP_ticket_lock_Release( + &the_spinlock->Lock, + &_Per_CPU_Get()->Lock_stats_context + ); +#endif + _ISR_Local_enable( level ); } - - status = _CORE_spinlock_Surrender( &the_spinlock->Spinlock, &lock_context ); - return _POSIX_Get_error( status ); +#endif + return 0; } |