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 | |
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 'cpukit')
24 files changed, 173 insertions, 723 deletions
diff --git a/cpukit/configure.ac b/cpukit/configure.ac index 136630bd7e..5a6c2e66bf 100644 --- a/cpukit/configure.ac +++ b/cpukit/configure.ac @@ -74,6 +74,7 @@ AC_CHECK_HEADERS([envlock.h]) AC_CHECK_DECLS([__env_lock],,,[#include <envlock.h>]) AC_CHECK_DECLS([__env_unlock],,,[#include <envlock.h>]) AC_CHECK_TYPES([struct _Thread_queue_Queue],[],[],[#include <sys/lock.h>]) +AC_CHECK_SIZEOF([pthread_spinlock_t],[],[],[#include <pthread.h>]) # Mandated by POSIX, older newlibs bogusly provided CLOCK_PROCESS_CPUTIME+CLOCK_THREAD_CPUTIME AC_CHECK_DECL([CLOCK_PROCESS_CPUTIME_ID],[],[AC_MSG_ERROR([missing define CLOCK_PROCESS_CPUTIME_ID])],[#include <time.h>]) diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h index c0fab6be97..e51b250f13 100644 --- a/cpukit/libcsupport/include/rtems/libcsupport.h +++ b/cpukit/libcsupport/include/rtems/libcsupport.h @@ -117,7 +117,6 @@ typedef struct { uint32_t active_mutexes; uint32_t active_rwlocks; uint32_t active_semaphores; - uint32_t active_spinlocks; uint32_t active_threads; uint32_t active_timers; } rtems_resource_posix_api; diff --git a/cpukit/libcsupport/src/resource_snapshot.c b/cpukit/libcsupport/src/resource_snapshot.c index 23177c4c37..d0dda9f7ca 100644 --- a/cpukit/libcsupport/src/resource_snapshot.c +++ b/cpukit/libcsupport/src/resource_snapshot.c @@ -49,7 +49,6 @@ #include <rtems/posix/pthreadimpl.h> #include <rtems/posix/rwlockimpl.h> #include <rtems/posix/semaphoreimpl.h> - #include <rtems/posix/spinlockimpl.h> #include <rtems/posix/timerimpl.h> #endif @@ -76,7 +75,6 @@ static const struct { { OBJECTS_POSIX_API, OBJECTS_POSIX_MUTEXES }, { OBJECTS_POSIX_API, OBJECTS_POSIX_RWLOCKS }, { OBJECTS_POSIX_API, OBJECTS_POSIX_SEMAPHORES }, - { OBJECTS_POSIX_API, OBJECTS_POSIX_SPINLOCKS }, { OBJECTS_POSIX_API, OBJECTS_POSIX_THREADS }, { OBJECTS_POSIX_API, OBJECTS_POSIX_TIMERS } #endif 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; } diff --git a/cpukit/rtems/src/rtemsobjectgetapiclassname.c b/cpukit/rtems/src/rtemsobjectgetapiclassname.c index dd92e6ce6e..07bfb1b3a0 100644 --- a/cpukit/rtems/src/rtemsobjectgetapiclassname.c +++ b/cpukit/rtems/src/rtemsobjectgetapiclassname.c @@ -54,7 +54,6 @@ static const rtems_assoc_t rtems_object_api_posix_assoc[] = { { "Condition Variable", OBJECTS_POSIX_CONDITION_VARIABLES, 0}, { "Timer", OBJECTS_POSIX_TIMERS, 0}, { "Barrier", OBJECTS_POSIX_BARRIERS, 0}, - { "Spinlock", OBJECTS_POSIX_SPINLOCKS, 0}, { "RWLock", OBJECTS_POSIX_RWLOCKS, 0}, { NULL, 0, 0} }; diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index be817bbf1d..3a718ba452 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -2068,10 +2068,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; #define CONFIGURE_MAXIMUM_POSIX_RWLOCKS \ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE) #endif - #if !defined(CONFIGURE_MAXIMUM_POSIX_SPINLOCKS) - #define CONFIGURE_MAXIMUM_POSIX_SPINLOCKS \ - rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE) - #endif #endif /* RTEMS_POSIX_API */ #endif /* CONFIGURE_UNLIMITED_OBJECTS */ @@ -2468,7 +2464,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; #include <rtems/posix/pthread.h> #include <rtems/posix/rwlock.h> #include <rtems/posix/semaphore.h> - #include <rtems/posix/spinlock.h> #include <rtems/posix/threadsup.h> #include <rtems/posix/timer.h> @@ -2616,23 +2611,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; /** * This configuration parameter specifies the maximum number of - * POSIX API spinlocks. - */ - #ifndef CONFIGURE_MAXIMUM_POSIX_SPINLOCKS - #define CONFIGURE_MAXIMUM_POSIX_SPINLOCKS 0 - #endif - - /** - * This macro is calculated to specify the memory required for - * POSIX API spinlocks. - * - * This is an internal parameter. - */ - #define CONFIGURE_MEMORY_FOR_POSIX_SPINLOCKS(_spinlocks) \ - _Configure_Object_RAM(_spinlocks, sizeof(POSIX_Spinlock_Control) ) - - /** - * This configuration parameter specifies the maximum number of * POSIX API rwlocks. */ #ifndef CONFIGURE_MAXIMUM_POSIX_RWLOCKS @@ -2871,8 +2849,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES( \ CONFIGURE_MAXIMUM_POSIX_SEMAPHORES) + \ CONFIGURE_MEMORY_FOR_POSIX_BARRIERS(CONFIGURE_MAXIMUM_POSIX_BARRIERS) + \ - CONFIGURE_MEMORY_FOR_POSIX_SPINLOCKS( \ - CONFIGURE_MAXIMUM_POSIX_SPINLOCKS) + \ CONFIGURE_MEMORY_FOR_POSIX_RWLOCKS( \ CONFIGURE_MAXIMUM_POSIX_RWLOCKS) + \ CONFIGURE_MEMORY_FOR_POSIX_TIMERS(CONFIGURE_MAXIMUM_POSIX_TIMERS)) @@ -3339,7 +3315,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; CONFIGURE_MAXIMUM_POSIX_SEMAPHORES, CONFIGURE_MAXIMUM_POSIX_BARRIERS, CONFIGURE_MAXIMUM_POSIX_RWLOCKS, - CONFIGURE_MAXIMUM_POSIX_SPINLOCKS, CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE, CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME }; @@ -3554,7 +3529,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; uint32_t POSIX_MESSAGE_QUEUES; uint32_t POSIX_SEMAPHORES; uint32_t POSIX_BARRIERS; - uint32_t POSIX_SPINLOCKS; uint32_t POSIX_RWLOCKS; #endif @@ -3608,7 +3582,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES ), CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES( CONFIGURE_MAXIMUM_POSIX_SEMAPHORES ), CONFIGURE_MEMORY_FOR_POSIX_BARRIERS( CONFIGURE_MAXIMUM_POSIX_BARRIERS ), - CONFIGURE_MEMORY_FOR_POSIX_SPINLOCKS( CONFIGURE_MAXIMUM_POSIX_SPINLOCKS ), CONFIGURE_MEMORY_FOR_POSIX_RWLOCKS( CONFIGURE_MAXIMUM_POSIX_RWLOCKS ), CONFIGURE_MEMORY_FOR_POSIX_TIMERS( CONFIGURE_MAXIMUM_POSIX_TIMERS ), #endif @@ -3680,7 +3653,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; (CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES != 0) || \ (CONFIGURE_MAXIMUM_POSIX_SEMAPHORES != 0) || \ (CONFIGURE_MAXIMUM_POSIX_BARRIERS != 0) || \ - (CONFIGURE_MAXIMUM_POSIX_SPINLOCKS != 0) || \ (CONFIGURE_MAXIMUM_POSIX_RWLOCKS != 0) || \ defined(CONFIGURE_POSIX_INIT_THREAD_TABLE)) #error "CONFIGURATION ERROR: POSIX API support not configured!!" diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 02b0bfb260..9b376c3f06 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -112,8 +112,6 @@ 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/corespinlock.h -include_rtems_score_HEADERS += include/rtems/score/corespinlockimpl.h include_rtems_score_HEADERS += include/rtems/score/corerwlock.h include_rtems_score_HEADERS += include/rtems/score/corerwlockimpl.h endif @@ -196,12 +194,6 @@ endif ## CORE_SEMAPHORE_C_FILES libscore_a_SOURCES += src/coresem.c -## CORE_SPINLOCK_C_FILES -if HAS_PTHREADS -libscore_a_SOURCES += src/corespinlockrelease.c \ - src/corespinlockwait.c -endif - ## HEAP_C_FILES libscore_a_SOURCES += src/heap.c src/heapallocate.c src/heapextend.c \ src/heapfree.c src/heapsizeofuserarea.c src/heapwalk.c src/heapgetinfo.c \ diff --git a/cpukit/score/include/rtems/score/corespinlock.h b/cpukit/score/include/rtems/score/corespinlock.h deleted file mode 100644 index 1666538bf6..0000000000 --- a/cpukit/score/include/rtems/score/corespinlock.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file rtems/score/corespinlock.h - * - * @brief Constants and Structures Associated with the Spinlock Handler - * - * This include file contains all the constants and structures associated - * with the Spinlock Handler. - */ - -/* - * COPYRIGHT (c) 1989-2006. - * 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_CORESPINLOCK_H -#define _RTEMS_SCORE_CORESPINLOCK_H - -#include <rtems/score/isrlock.h> -#include <rtems/score/thread.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup ScoreSpinlock Spinlock Handler - * - * @ingroup Score - * - * This handler encapsulates functionality which provides the foundation - * Spinlock services used in all of the APIs supported by RTEMS. - */ -/**@{*/ - -/** - * The following defines the control block used to manage each - * spinlock. - */ -typedef struct { - /** - * @brief Lock to protect the other fields. - * - * This implementation is a bit stupid. However, test cases in the Linux - * Test Project do things like sleep() and printf() while owning a - * pthread_spinlock_t, e.g. - * testcases/open_posix_testsuite/conformance/interfaces/pthread_spin_lock/1-2.c - */ - ISR_LOCK_MEMBER( Lock ) - - /** This field is the lock. - */ - uint32_t lock; - - /** This field is a count of the current number of threads using - * this spinlock. It includes the thread holding the lock as well - * as those waiting. - */ - uint32_t users; - - /** This field is the Id of the thread holding the lock. It may or may - * not be the thread which acquired it. - */ - Thread_Control *holder; -} CORE_spinlock_Control; - -/**@}*/ - -#ifdef __cplusplus -} -#endif - -#endif -/* end of include file */ diff --git a/cpukit/score/include/rtems/score/corespinlockimpl.h b/cpukit/score/include/rtems/score/corespinlockimpl.h deleted file mode 100644 index 140529b573..0000000000 --- a/cpukit/score/include/rtems/score/corespinlockimpl.h +++ /dev/null @@ -1,130 +0,0 @@ -/** - * @file - * - * @brief Inlined Routines Associated with the SuperCore Spinlock - * - * This include file contains all of the inlined routines associated - * with the SuperCore spinlock. - */ - -/* - * 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_CORESPINLOCKIMPL_H -#define _RTEMS_SCORE_CORESPINLOCKIMPL_H - -#include <rtems/score/corespinlock.h> -#include <rtems/score/status.h> -#include <rtems/score/watchdog.h> - -#include <string.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @addtogroup ScoreSpinlock - */ -/**@{**/ - -/** This indicates the lock is available. */ -#define CORE_SPINLOCK_UNLOCKED 0 - -/** This indicates the lock is unavailable. */ -#define CORE_SPINLOCK_LOCKED 1 - -/** - * @brief Initialize the spinlock. - * - * This routine initializes the spinlock based on the parameters passed. - * - * @param[in] the_spinlock is the spinlock control block to initialize - */ -RTEMS_INLINE_ROUTINE void _CORE_spinlock_Initialize( - CORE_spinlock_Control *the_spinlock -) -{ - memset( the_spinlock, 0, sizeof( *the_spinlock ) ); -} - -RTEMS_INLINE_ROUTINE void _CORE_spinlock_Acquire_critical( - CORE_spinlock_Control *the_spinlock, - ISR_lock_Context *lock_context -) -{ - _ISR_lock_Acquire( &the_spinlock->Lock, lock_context ); -} - -RTEMS_INLINE_ROUTINE void _CORE_spinlock_Release( - CORE_spinlock_Control *the_spinlock, - ISR_lock_Context *lock_context -) -{ - _ISR_lock_Release_and_ISR_enable( &the_spinlock->Lock, lock_context ); -} - -/** - * @brief Wait for spinlock. - * - * This routine wait for the spinlock to be released. If the spinlock - * is set to automatic and this is the appropriate thread, then it returns - * immediately. Otherwise, the calling thread is blocked until the spinlock - * is released. - * - * @param[in] the_spinlock is the spinlock to wait for - * @param[in] wait is true if willing to wait - * @param[in] timeout is the maximum number of ticks to spin (0 is forever) - * - * @retval A status is returned which indicates the success or failure of - * this operation. - */ -Status_Control _CORE_spinlock_Seize( - CORE_spinlock_Control *the_spinlock, - bool wait, - Watchdog_Interval timeout, - ISR_lock_Context *lock_context -); - -/** - * @brief Manually release the spinlock. - * - * This routine manually releases the spinlock. All of the threads waiting - * for the spinlock will be readied. - * - * @param[in] the_spinlock is the spinlock to surrender - */ -Status_Control _CORE_spinlock_Surrender( - CORE_spinlock_Control *the_spinlock, - ISR_lock_Context *lock_context -); - -/** - * This method is used to determine if the spinlock is available or not. - * - * @param[in] the_spinlock will be checked - * - * @return This method will return true if the spinlock is busy - * and false otherwise. - */ -RTEMS_INLINE_ROUTINE bool _CORE_spinlock_Is_busy( - CORE_spinlock_Control *the_spinlock -) -{ - return (the_spinlock->users != 0); -} - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif -/* end of include file */ diff --git a/cpukit/score/include/rtems/score/objectimpl.h b/cpukit/score/include/rtems/score/objectimpl.h index f5beb3b971..a00aa2276e 100644 --- a/cpukit/score/include/rtems/score/objectimpl.h +++ b/cpukit/score/include/rtems/score/objectimpl.h @@ -92,8 +92,7 @@ typedef enum { OBJECTS_POSIX_CONDITION_VARIABLES = 8, OBJECTS_POSIX_TIMERS = 9, OBJECTS_POSIX_BARRIERS = 10, - OBJECTS_POSIX_SPINLOCKS = 11, - OBJECTS_POSIX_RWLOCKS = 12 + OBJECTS_POSIX_RWLOCKS = 11 } Objects_POSIX_API; /** This macro is used to generically specify the last API index. */ diff --git a/cpukit/score/include/rtems/sysinit.h b/cpukit/score/include/rtems/sysinit.h index ad68c45c5c..a0ab17c8ec 100644 --- a/cpukit/score/include/rtems/sysinit.h +++ b/cpukit/score/include/rtems/sysinit.h @@ -54,7 +54,6 @@ extern "C" { #define RTEMS_SYSINIT_POSIX_TIMER 000366 #define RTEMS_SYSINIT_POSIX_BARRIER 000367 #define RTEMS_SYSINIT_POSIX_RWLOCK 000368 -#define RTEMS_SYSINIT_POSIX_SPINLOCK 000369 #define RTEMS_SYSINIT_POSIX_CLEANUP 00036a #define RTEMS_SYSINIT_POSIX_KEYS 00036b #define RTEMS_SYSINIT_IDLE_THREADS 000380 diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am index a6943244b5..4d468e5dde 100644 --- a/cpukit/score/preinstall.am +++ b/cpukit/score/preinstall.am @@ -409,14 +409,6 @@ $(PROJECT_INCLUDE)/rtems/score/basedefs.h: include/rtems/score/basedefs.h $(PROJ PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/basedefs.h if HAS_PTHREADS -$(PROJECT_INCLUDE)/rtems/score/corespinlock.h: include/rtems/score/corespinlock.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/corespinlock.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/corespinlock.h - -$(PROJECT_INCLUDE)/rtems/score/corespinlockimpl.h: include/rtems/score/corespinlockimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/corespinlockimpl.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/corespinlockimpl.h - $(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 diff --git a/cpukit/score/src/corespinlockrelease.c b/cpukit/score/src/corespinlockrelease.c deleted file mode 100644 index 4a4f9528b3..0000000000 --- a/cpukit/score/src/corespinlockrelease.c +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file - * - * @brief Release a Spinlock - * @ingroup ScoreSpinlock - */ - -/* - * COPYRIGHT (c) 1989-2006. - * 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/score/corespinlockimpl.h> -#include <rtems/score/percpu.h> - -Status_Control _CORE_spinlock_Surrender( - CORE_spinlock_Control *the_spinlock, - ISR_lock_Context *lock_context -) -{ - _CORE_spinlock_Acquire_critical( the_spinlock, lock_context ); - - /* - * It must locked by the current thread before it can be unlocked. - */ - if ( - the_spinlock->lock != CORE_SPINLOCK_LOCKED - || the_spinlock->holder != _Thread_Executing - ) { - _CORE_spinlock_Release( the_spinlock, lock_context ); - return STATUS_NOT_OWNER; - } - - /* - * Let it be unlocked. - */ - the_spinlock->users -= 1; - the_spinlock->lock = CORE_SPINLOCK_UNLOCKED; - the_spinlock->holder = 0; - - _CORE_spinlock_Release( the_spinlock, lock_context ); - return STATUS_SUCCESSFUL; -} diff --git a/cpukit/score/src/corespinlockwait.c b/cpukit/score/src/corespinlockwait.c deleted file mode 100644 index 4aacb60b74..0000000000 --- a/cpukit/score/src/corespinlockwait.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * @file - * - * @brief Wait for Spinlock - * @ingroup ScoreSpinlock - */ - -/* - * 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 <rtems/score/corespinlockimpl.h> -#include <rtems/score/percpu.h> - -Status_Control _CORE_spinlock_Seize( - CORE_spinlock_Control *the_spinlock, - bool wait, - Watchdog_Interval timeout, - ISR_lock_Context *lock_context -) -{ - Thread_Control *executing; - - #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API) - Watchdog_Interval limit = _Watchdog_Ticks_since_boot + timeout; - #endif - - executing = _Thread_Executing; - - _CORE_spinlock_Acquire_critical( the_spinlock, lock_context ); - if ( the_spinlock->lock == CORE_SPINLOCK_LOCKED && - the_spinlock->holder == executing ) { - _CORE_spinlock_Release( the_spinlock, lock_context ); - return STATUS_NESTING_NOT_ALLOWED; - } - the_spinlock->users += 1; - for ( ;; ) { - if ( the_spinlock->lock == CORE_SPINLOCK_UNLOCKED ) { - the_spinlock->lock = CORE_SPINLOCK_LOCKED; - the_spinlock->holder = executing; - _CORE_spinlock_Release( the_spinlock, lock_context ); - return STATUS_SUCCESSFUL; - } - - /* - * Spinlock is unavailable. If not willing to wait, return. - */ - if ( !wait ) { - the_spinlock->users -= 1; - _CORE_spinlock_Release( the_spinlock, lock_context ); - return STATUS_UNAVAILABLE; - } - - #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API) - /* - * They are willing to wait but there could be a timeout. - */ - if ( timeout && (limit <= _Watchdog_Ticks_since_boot) ) { - the_spinlock->users -= 1; - _CORE_spinlock_Release( the_spinlock, lock_context ); - return STATUS_TIMEOUT; - } - #endif - - /* - * The thread is willing to spin so let's set things up so - * another thread has a chance of running. This spinlock has - * to be released by either another thread or an ISR. Since - * POSIX does not say anything about ISRs, that implies that - * another thread must be able to run while spinning. We are - * not blocking so that implies we are at least preemptible - * and possibly time-sliced. - * - * So first, we will enable interrpts to allow for them to happen. - * Then we will "flash" the thread dispatching critical section - * so other threads have a chance to run. - * - * A spinlock cannot be deleted while it is being used so we are - * safe from deletion. - */ - - _CORE_spinlock_Release( the_spinlock, lock_context ); - - /* - * An ISR could occur here. Another thread could get dispatched here. - * Reenter the critical sections so we can attempt the lock again. - */ - - _ISR_lock_ISR_disable( lock_context ); - _CORE_spinlock_Acquire_critical( the_spinlock, lock_context ); - } - -} |