From c42be504c92d76d2e06d0fc8ebd05fc913376d2d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 16 Nov 2016 14:50:09 +0100 Subject: 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 . 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. --- cpukit/posix/Makefile.am | 14 ++-- cpukit/posix/include/rtems/posix/config.h | 6 -- cpukit/posix/include/rtems/posix/spinlock.h | 63 ---------------- cpukit/posix/include/rtems/posix/spinlockimpl.h | 81 ++++++++++----------- cpukit/posix/preinstall.am | 12 ++-- cpukit/posix/src/pspin.c | 51 ------------- cpukit/posix/src/pspindestroy.c | 30 ++------ cpukit/posix/src/pspininit.c | 52 ++------------ cpukit/posix/src/pspinlock.c | 96 +++++++++++++++++++++---- cpukit/posix/src/pspintrylock.c | 42 ----------- cpukit/posix/src/pspinunlock.c | 36 +++++++--- 11 files changed, 171 insertions(+), 312 deletions(-) delete mode 100644 cpukit/posix/include/rtems/posix/spinlock.h delete mode 100644 cpukit/posix/src/pspin.c delete mode 100644 cpukit/posix/src/pspintrylock.c (limited to 'cpukit/posix') 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 @@ -110,12 +110,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 -#include - -#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 -#include -#include - #include +#include + +#if defined(RTEMS_SMP) +#include +#include +#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 - -#include -#include -#include -#include - -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 -#include - 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 -#include - -#include #include -/* - * 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 -#include + +#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 -#include - -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 -#include -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; } -- cgit v1.2.3