[rtems commit] score: Avoid Giant lock for CORE spinlock
Sebastian Huber
sebh at rtems.org
Mon Mar 21 06:45:31 UTC 2016
Module: rtems
Branch: master
Commit: 5a5fb3b9d6d99d6751d129458217f1a3b5b85ff8
Changeset: http://git.rtems.org/rtems/commit/?id=5a5fb3b9d6d99d6751d129458217f1a3b5b85ff8
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Fri Mar 18 14:03:01 2016 +0100
score: Avoid Giant lock for CORE spinlock
Use an ISR lock to protect the spinlock state. Remove empty attributes.
Update #2555.
---
cpukit/posix/include/rtems/posix/spinlockimpl.h | 27 ++++------
cpukit/posix/src/pspindestroy.c | 63 +++++++---------------
cpukit/posix/src/pspininit.c | 5 +-
cpukit/posix/src/pspinlock.c | 50 ++++++-----------
cpukit/posix/src/pspintrylock.c | 52 +++++-------------
cpukit/posix/src/pspinunlock.c | 47 ++++------------
cpukit/score/Makefile.am | 2 +-
cpukit/score/include/rtems/score/corespinlock.h | 30 +++++------
.../score/include/rtems/score/corespinlockimpl.h | 55 +++++++++++--------
cpukit/score/src/corespinlock.c | 37 -------------
cpukit/score/src/corespinlockrelease.c | 19 +++----
cpukit/score/src/corespinlockwait.c | 63 +++++++++-------------
12 files changed, 149 insertions(+), 301 deletions(-)
diff --git a/cpukit/posix/include/rtems/posix/spinlockimpl.h b/cpukit/posix/include/rtems/posix/spinlockimpl.h
index 01fe372..0904050 100644
--- a/cpukit/posix/include/rtems/posix/spinlockimpl.h
+++ b/cpukit/posix/include/rtems/posix/spinlockimpl.h
@@ -75,26 +75,19 @@ RTEMS_INLINE_ROUTINE void _POSIX_Spinlock_Free (
_Objects_Free( &_POSIX_Spinlock_Information, &the_spinlock->Object );
}
-/**
- * @brief Get a spinlock control block.
- *
- * This function maps spinlock IDs to spinlock control blocks.
- * If ID corresponds to a local spinlock, then it returns
- * the_spinlock control pointer which maps to ID and location
- * is set to OBJECTS_LOCAL. if the spinlock ID is global and
- * resides on a remote node, then location is set to OBJECTS_REMOTE,
- * and the_spinlock is undefined. Otherwise, location is set
- * to OBJECTS_ERROR and the_spinlock is undefined.
- */
-RTEMS_INLINE_ROUTINE POSIX_Spinlock_Control *_POSIX_Spinlock_Get (
+RTEMS_INLINE_ROUTINE POSIX_Spinlock_Control *_POSIX_Spinlock_Get(
pthread_spinlock_t *spinlock,
- Objects_Locations *location
+ ISR_lock_Context *lock_context
)
{
- return (POSIX_Spinlock_Control *) _Objects_Get(
- &_POSIX_Spinlock_Information,
- (Objects_Id) *spinlock,
- location
+ if ( spinlock == NULL ) {
+ return NULL;
+ }
+
+ return (POSIX_Spinlock_Control *) _Objects_Get_local(
+ &_POSIX_Spinlock_Information,
+ *spinlock,
+ lock_context
);
}
diff --git a/cpukit/posix/src/pspindestroy.c b/cpukit/posix/src/pspindestroy.c
index ab45ad1..42a6e76 100644
--- a/cpukit/posix/src/pspindestroy.c
+++ b/cpukit/posix/src/pspindestroy.c
@@ -18,58 +18,35 @@
#include "config.h"
#endif
-#include <pthread.h>
-#include <errno.h>
-
-#include <rtems/system.h>
#include <rtems/posix/spinlockimpl.h>
-/**
- * This directive allows a thread to delete a spinlock specified by
- * the spinlock id. The spinlock is freed back to the inactive
- * spinlock chain.
- *
- * @param[in] spinlock is the spinlock id
- *
- * @return This method returns 0 if there was not an
- * error. Otherwise, a status code is returned indicating the
- * source of the error.
- */
-int pthread_spin_destroy(
- pthread_spinlock_t *spinlock
-)
-{
- POSIX_Spinlock_Control *the_spinlock = NULL;
- Objects_Locations location;
+#include <errno.h>
- if ( !spinlock )
- return EINVAL;
+int pthread_spin_destroy( pthread_spinlock_t *spinlock )
+{
+ POSIX_Spinlock_Control *the_spinlock;
+ ISR_lock_Context lock_context;
_Objects_Allocator_lock();
- the_spinlock = _POSIX_Spinlock_Get( spinlock, &location );
- switch ( location ) {
- case OBJECTS_LOCAL:
- if ( _CORE_spinlock_Is_busy( &the_spinlock->Spinlock ) ) {
- _Objects_Put( &the_spinlock->Object );
- return EBUSY;
- }
-
- _Objects_Close( &_POSIX_Spinlock_Information, &the_spinlock->Object );
- _Objects_Put( &the_spinlock->Object );
- _POSIX_Spinlock_Free( the_spinlock );
- _Objects_Allocator_unlock();
+ the_spinlock = _POSIX_Spinlock_Get( spinlock, &lock_context );
+ if ( the_spinlock == NULL ) {
+ _Objects_Allocator_unlock();
+ return EINVAL;
+ }
- return 0;
+ _CORE_spinlock_Acquire_critical( &the_spinlock->Spinlock, &lock_context );
-#if defined(RTEMS_MULTIPROCESSING)
- case OBJECTS_REMOTE:
-#endif
- case OBJECTS_ERROR:
- break;
+ if ( _CORE_spinlock_Is_busy( &the_spinlock->Spinlock ) ) {
+ _CORE_spinlock_Release( &the_spinlock->Spinlock, &lock_context );
+ _Objects_Allocator_unlock();
+ return EBUSY;
}
- _Objects_Allocator_unlock();
+ _CORE_spinlock_Release( &the_spinlock->Spinlock, &lock_context );
- return EINVAL;
+ _Objects_Close( &_POSIX_Spinlock_Information, &the_spinlock->Object );
+ _POSIX_Spinlock_Free( the_spinlock );
+ _Objects_Allocator_unlock();
+ return 0;
}
diff --git a/cpukit/posix/src/pspininit.c b/cpukit/posix/src/pspininit.c
index 02b07c8..bc131e2 100644
--- a/cpukit/posix/src/pspininit.c
+++ b/cpukit/posix/src/pspininit.c
@@ -47,7 +47,6 @@ int pthread_spin_init(
)
{
POSIX_Spinlock_Control *the_spinlock;
- CORE_spinlock_Attributes attributes;
if ( !spinlock )
return EINVAL;
@@ -67,9 +66,7 @@ int pthread_spin_init(
return EAGAIN;
}
- _CORE_spinlock_Initialize_attributes( &attributes );
-
- _CORE_spinlock_Initialize( &the_spinlock->Spinlock, &attributes );
+ _CORE_spinlock_Initialize( &the_spinlock->Spinlock );
_Objects_Open_u32( &_POSIX_Spinlock_Information, &the_spinlock->Object, 0 );
diff --git a/cpukit/posix/src/pspinlock.c b/cpukit/posix/src/pspinlock.c
index d13ffe6..502177c 100644
--- a/cpukit/posix/src/pspinlock.c
+++ b/cpukit/posix/src/pspinlock.c
@@ -18,46 +18,26 @@
#include "config.h"
#endif
-#include <pthread.h>
-#include <errno.h>
-
-#include <rtems/system.h>
#include <rtems/posix/spinlockimpl.h>
-/**
- * This directive allows a thread to wait at a spinlock.
- *
- * @param[in] spinlock is spinlock id
- *
- * @return This method returns 0 if there was not an
- * error. Otherwise, a status code is returned indicating the
- * source of the error.
- */
-int pthread_spin_lock(
- pthread_spinlock_t *spinlock
-)
+#include <errno.h>
+
+int pthread_spin_lock( pthread_spinlock_t *spinlock )
{
- POSIX_Spinlock_Control *the_spinlock = NULL;
- Objects_Locations location;
- CORE_spinlock_Status status;
+ POSIX_Spinlock_Control *the_spinlock;
+ ISR_lock_Context lock_context;
+ CORE_spinlock_Status status;
- if ( !spinlock )
+ the_spinlock = _POSIX_Spinlock_Get( spinlock, &lock_context );
+ if ( the_spinlock == NULL ) {
return EINVAL;
-
- the_spinlock = _POSIX_Spinlock_Get( spinlock, &location );
- switch ( location ) {
-
- case OBJECTS_LOCAL:
- status = _CORE_spinlock_Wait( &the_spinlock->Spinlock, true, 0 );
- _Objects_Put( &the_spinlock->Object );
- return _POSIX_Spinlock_Translate_core_spinlock_return_code( status );
-
-#if defined(RTEMS_MULTIPROCESSING)
- case OBJECTS_REMOTE:
-#endif
- case OBJECTS_ERROR:
- break;
}
- return EINVAL;
+ status = _CORE_spinlock_Seize(
+ &the_spinlock->Spinlock,
+ true,
+ 0,
+ &lock_context
+ );
+ return _POSIX_Spinlock_Translate_core_spinlock_return_code( status );
}
diff --git a/cpukit/posix/src/pspintrylock.c b/cpukit/posix/src/pspintrylock.c
index d304908..5f132a3 100644
--- a/cpukit/posix/src/pspintrylock.c
+++ b/cpukit/posix/src/pspintrylock.c
@@ -18,50 +18,26 @@
#include "config.h"
#endif
-#include <pthread.h>
-#include <errno.h>
-
-#include <rtems/system.h>
#include <rtems/posix/spinlockimpl.h>
-/*
- * pthread_spin_trylock
- *
- * This directive allows a thread to poll an attempt at locking a spinlock.
- *
- * Input parameters:
- * spinlock - spinlock id
- *
- * Output parameters:
- * 0 - if successful
- * error code - if unsuccessful
- */
+#include <errno.h>
-int pthread_spin_trylock(
- pthread_spinlock_t *spinlock
-)
+int pthread_spin_trylock( pthread_spinlock_t *spinlock )
{
- POSIX_Spinlock_Control *the_spinlock = NULL;
- Objects_Locations location;
- CORE_spinlock_Status status;
+ POSIX_Spinlock_Control *the_spinlock;
+ ISR_lock_Context lock_context;
+ CORE_spinlock_Status status;
- if ( !spinlock )
+ the_spinlock = _POSIX_Spinlock_Get( spinlock, &lock_context );
+ if ( the_spinlock == NULL ) {
return EINVAL;
-
- the_spinlock = _POSIX_Spinlock_Get( spinlock, &location );
- switch ( location ) {
-
- case OBJECTS_LOCAL:
- status = _CORE_spinlock_Wait( &the_spinlock->Spinlock, false, 0 );
- _Objects_Put( &the_spinlock->Object );
- return _POSIX_Spinlock_Translate_core_spinlock_return_code( status );
-
-#if defined(RTEMS_MULTIPROCESSING)
- case OBJECTS_REMOTE:
-#endif
- case OBJECTS_ERROR:
- break;
}
- return EINVAL;
+ status = _CORE_spinlock_Seize(
+ &the_spinlock->Spinlock,
+ false,
+ 0,
+ &lock_context
+ );
+ return _POSIX_Spinlock_Translate_core_spinlock_return_code( status );
}
diff --git a/cpukit/posix/src/pspinunlock.c b/cpukit/posix/src/pspinunlock.c
index 3a483ad..35dbcb9 100644
--- a/cpukit/posix/src/pspinunlock.c
+++ b/cpukit/posix/src/pspinunlock.c
@@ -20,50 +20,21 @@
#include "config.h"
#endif
-#include <pthread.h>
-#include <errno.h>
-
-#include <rtems/system.h>
#include <rtems/posix/spinlockimpl.h>
-/*
- * pthread_spin_unlock
- *
- * This directive allows a thread to wait at a spinlock.
- *
- * Input parameters:
- * spinlock - spinlock id
- *
- * Output parameters:
- * 0 - if successful
- * error code - if unsuccessful
- */
+#include <errno.h>
-int pthread_spin_unlock(
- pthread_spinlock_t *spinlock
-)
+int pthread_spin_unlock( pthread_spinlock_t *spinlock )
{
- POSIX_Spinlock_Control *the_spinlock = NULL;
- Objects_Locations location;
- CORE_spinlock_Status status;
+ POSIX_Spinlock_Control *the_spinlock;
+ ISR_lock_Context lock_context;
+ CORE_spinlock_Status status;
- if ( !spinlock )
+ the_spinlock = _POSIX_Spinlock_Get( spinlock, &lock_context );
+ if ( the_spinlock == NULL ) {
return EINVAL;
-
- the_spinlock = _POSIX_Spinlock_Get( spinlock, &location );
- switch ( location ) {
-
- case OBJECTS_LOCAL:
- status = _CORE_spinlock_Release( &the_spinlock->Spinlock );
- _Objects_Put( &the_spinlock->Object );
- return _POSIX_Spinlock_Translate_core_spinlock_return_code( status );
-
-#if defined(RTEMS_MULTIPROCESSING)
- case OBJECTS_REMOTE:
-#endif
- case OBJECTS_ERROR:
- break;
}
- return EINVAL;
+ status = _CORE_spinlock_Surrender( &the_spinlock->Spinlock, &lock_context );
+ return _POSIX_Spinlock_Translate_core_spinlock_return_code( status );
}
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index b6824ad..6ff4e02 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -194,7 +194,7 @@ libscore_a_SOURCES += src/coresem.c
## CORE_SPINLOCK_C_FILES
if HAS_PTHREADS
-libscore_a_SOURCES += src/corespinlock.c src/corespinlockrelease.c \
+libscore_a_SOURCES += src/corespinlockrelease.c \
src/corespinlockwait.c
endif
diff --git a/cpukit/score/include/rtems/score/corespinlock.h b/cpukit/score/include/rtems/score/corespinlock.h
index ca50eed..1666538 100644
--- a/cpukit/score/include/rtems/score/corespinlock.h
+++ b/cpukit/score/include/rtems/score/corespinlock.h
@@ -19,7 +19,8 @@
#ifndef _RTEMS_SCORE_CORESPINLOCK_H
#define _RTEMS_SCORE_CORESPINLOCK_H
-#include <rtems/score/object.h>
+#include <rtems/score/isrlock.h>
+#include <rtems/score/thread.h>
#ifdef __cplusplus
extern "C" {
@@ -36,37 +37,34 @@ extern "C" {
/**@{*/
/**
- * The following defines the control block used to manage the
- * attributes of each spinlock.
- */
-typedef struct {
- /** This element indicates XXX
- */
- uint32_t XXX;
-} CORE_spinlock_Attributes;
-
-/**
* The following defines the control block used to manage each
* spinlock.
*/
typedef struct {
- /** XXX may not be needed */
- CORE_spinlock_Attributes Attributes;
+ /**
+ * @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.
*/
- volatile uint32_t 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.
*/
- volatile uint32_t users;
+ 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.
*/
- volatile Objects_Id holder;
+ Thread_Control *holder;
} CORE_spinlock_Control;
/**@}*/
diff --git a/cpukit/score/include/rtems/score/corespinlockimpl.h b/cpukit/score/include/rtems/score/corespinlockimpl.h
index fe6f9b6..189bddb 100644
--- a/cpukit/score/include/rtems/score/corespinlockimpl.h
+++ b/cpukit/score/include/rtems/score/corespinlockimpl.h
@@ -22,6 +22,8 @@
#include <rtems/score/corespinlock.h>
#include <rtems/score/watchdog.h>
+#include <string.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -78,12 +80,29 @@ typedef enum {
* This routine initializes the spinlock based on the parameters passed.
*
* @param[in] the_spinlock is the spinlock control block to initialize
- * @param[in] the_spinlock_attributes define the behavior of this instance
*/
-void _CORE_spinlock_Initialize(
- CORE_spinlock_Control *the_spinlock,
- CORE_spinlock_Attributes *the_spinlock_attributes
-);
+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.
@@ -100,10 +119,11 @@ void _CORE_spinlock_Initialize(
* @retval A status is returned which indicates the success or failure of
* this operation.
*/
-CORE_spinlock_Status _CORE_spinlock_Wait(
- CORE_spinlock_Control *the_spinlock,
- bool wait,
- Watchdog_Interval timeout
+CORE_spinlock_Status _CORE_spinlock_Seize(
+ CORE_spinlock_Control *the_spinlock,
+ bool wait,
+ Watchdog_Interval timeout,
+ ISR_lock_Context *lock_context
);
/**
@@ -114,23 +134,12 @@ CORE_spinlock_Status _CORE_spinlock_Wait(
*
* @param[in] the_spinlock is the spinlock to surrender
*/
-CORE_spinlock_Status _CORE_spinlock_Release(
- CORE_spinlock_Control *the_spinlock
+CORE_spinlock_Status _CORE_spinlock_Surrender(
+ CORE_spinlock_Control *the_spinlock,
+ ISR_lock_Context *lock_context
);
/**
- * This method is used to initialize core spinlock attributes.
- *
- * @param[in] the_attributes pointer to the attributes to initialize.
- */
-RTEMS_INLINE_ROUTINE void _CORE_spinlock_Initialize_attributes(
- CORE_spinlock_Attributes *the_attributes
-)
-{
- the_attributes->XXX = 0;
-}
-
-/**
* This method is used to determine if the spinlock is available or not.
*
* @param[in] the_spinlock will be checked
diff --git a/cpukit/score/src/corespinlock.c b/cpukit/score/src/corespinlock.c
deleted file mode 100644
index b84eb2e..0000000
--- a/cpukit/score/src/corespinlock.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * @file
- *
- * @brief Initialize 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/system.h>
-#include <rtems/score/corespinlockimpl.h>
-#include <rtems/score/thread.h>
-
-void _CORE_spinlock_Initialize(
- CORE_spinlock_Control *the_spinlock,
- CORE_spinlock_Attributes *the_spinlock_attributes
-)
-{
-
- the_spinlock->Attributes = *the_spinlock_attributes;
-
- the_spinlock->lock = 0;
- the_spinlock->users = 0;
- the_spinlock->holder = 0;
-}
diff --git a/cpukit/score/src/corespinlockrelease.c b/cpukit/score/src/corespinlockrelease.c
index c10337a..358d352 100644
--- a/cpukit/score/src/corespinlockrelease.c
+++ b/cpukit/score/src/corespinlockrelease.c
@@ -20,30 +20,27 @@
#include <rtems/score/corespinlockimpl.h>
#include <rtems/score/percpu.h>
-#include <rtems/score/thread.h>
-#include <rtems/score/watchdog.h>
-CORE_spinlock_Status _CORE_spinlock_Release(
- CORE_spinlock_Control *the_spinlock
+CORE_spinlock_Status _CORE_spinlock_Surrender(
+ CORE_spinlock_Control *the_spinlock,
+ ISR_lock_Context *lock_context
)
{
- ISR_Level level;
-
- _ISR_Disable( level );
+ _CORE_spinlock_Acquire_critical( the_spinlock, lock_context );
/*
* It must locked before it can be unlocked.
*/
if ( the_spinlock->lock == CORE_SPINLOCK_UNLOCKED ) {
- _ISR_Enable( level );
+ _CORE_spinlock_Release( the_spinlock, lock_context );
return CORE_SPINLOCK_NOT_LOCKED;
}
/*
* It must locked by the current thread before it can be unlocked.
*/
- if ( the_spinlock->holder != _Thread_Executing->Object.id ) {
- _ISR_Enable( level );
+ if ( the_spinlock->holder != _Thread_Executing ) {
+ _CORE_spinlock_Release( the_spinlock, lock_context );
return CORE_SPINLOCK_NOT_HOLDER;
}
@@ -54,6 +51,6 @@ CORE_spinlock_Status _CORE_spinlock_Release(
the_spinlock->lock = CORE_SPINLOCK_UNLOCKED;
the_spinlock->holder = 0;
- _ISR_Enable( level );
+ _CORE_spinlock_Release( the_spinlock, lock_context );
return CORE_SPINLOCK_SUCCESSFUL;
}
diff --git a/cpukit/score/src/corespinlockwait.c b/cpukit/score/src/corespinlockwait.c
index 1f10296..cc939c2 100644
--- a/cpukit/score/src/corespinlockwait.c
+++ b/cpukit/score/src/corespinlockwait.c
@@ -18,48 +18,36 @@
#include "config.h"
#endif
-#include <rtems/system.h>
#include <rtems/score/corespinlockimpl.h>
-#include <rtems/score/thread.h>
-#include <rtems/score/threaddispatch.h>
+#include <rtems/score/percpu.h>
-/*
- * _CORE_spinlock_Wait
- *
- * This function waits for the spinlock to become available. Optionally,
- * a limit may be placed on the duration of the spin.
- *
- * Input parameters:
- * the_spinlock - the spinlock control block to initialize
- * wait - true if willing to wait
- * timeout - the maximum number of ticks to spin (0 is forever)
- *
- * Output parameters: NONE
- */
-
-CORE_spinlock_Status _CORE_spinlock_Wait(
- CORE_spinlock_Control *the_spinlock,
- bool wait,
- Watchdog_Interval timeout
+CORE_spinlock_Status _CORE_spinlock_Seize(
+ CORE_spinlock_Control *the_spinlock,
+ bool wait,
+ Watchdog_Interval timeout,
+ ISR_lock_Context *lock_context
)
{
- ISR_Level level;
+ Thread_Control *executing;
+
#if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
Watchdog_Interval limit = _Watchdog_Ticks_since_boot + timeout;
#endif
- _ISR_Disable( level );
- if ( (the_spinlock->lock == CORE_SPINLOCK_LOCKED) &&
- (the_spinlock->holder == _Thread_Executing->Object.id) ) {
- _ISR_Enable( level );
+ 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 CORE_SPINLOCK_HOLDER_RELOCKING;
}
the_spinlock->users += 1;
for ( ;; ) {
if ( the_spinlock->lock == CORE_SPINLOCK_UNLOCKED ) {
the_spinlock->lock = CORE_SPINLOCK_LOCKED;
- the_spinlock->holder = _Thread_Executing->Object.id;
- _ISR_Enable( level );
+ the_spinlock->holder = executing;
+ _CORE_spinlock_Release( the_spinlock, lock_context );
return CORE_SPINLOCK_SUCCESSFUL;
}
@@ -68,7 +56,7 @@ CORE_spinlock_Status _CORE_spinlock_Wait(
*/
if ( !wait ) {
the_spinlock->users -= 1;
- _ISR_Enable( level );
+ _CORE_spinlock_Release( the_spinlock, lock_context );
return CORE_SPINLOCK_UNAVAILABLE;
}
@@ -78,7 +66,7 @@ CORE_spinlock_Status _CORE_spinlock_Wait(
*/
if ( timeout && (limit <= _Watchdog_Ticks_since_boot) ) {
the_spinlock->users -= 1;
- _ISR_Enable( level );
+ _CORE_spinlock_Release( the_spinlock, lock_context );
return CORE_SPINLOCK_TIMEOUT;
}
#endif
@@ -100,16 +88,15 @@ CORE_spinlock_Status _CORE_spinlock_Wait(
* safe from deletion.
*/
- _ISR_Enable( level );
- /* An ISR could occur here */
-
- _Thread_Enable_dispatch();
- /* Another thread could get dispatched here */
+ _CORE_spinlock_Release( the_spinlock, lock_context );
- /* Reenter the critical sections so we can attempt the lock again. */
- _Thread_Disable_dispatch();
+ /*
+ * An ISR could occur here. Another thread could get dispatched here.
+ * Reenter the critical sections so we can attempt the lock again.
+ */
- _ISR_Disable( level );
+ _ISR_lock_ISR_disable( lock_context );
+ _CORE_spinlock_Acquire_critical( the_spinlock, lock_context );
}
}
More information about the vc
mailing list