[rtems commit] score: Add local context to SMP lock API

Sebastian Huber sebh at rtems.org
Tue Mar 11 09:57:00 UTC 2014


Module:    rtems
Branch:    master
Commit:    d50acdbb6c8213114ce887a56daea02697c9e1a1
Changeset: http://git.rtems.org/rtems/commit/?id=d50acdbb6c8213114ce887a56daea02697c9e1a1

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Mar 10 08:25:32 2014 +0100

score: Add local context to SMP lock API

Add a local context structure to the SMP lock API for acquire and
release pairs.  This context can be used to store the ISR level and
profiling information.  It may be later used to enable more
sophisticated lock algorithms, e.g. MCS locks.

There is only one lock that cannot be used with a local context.  This
is the per-CPU lock since here we would have to transfer the local
context through a context switch which is very complicated.

---

 c/src/lib/libbsp/sparc/leon3/include/leon.h       |   32 +++---
 cpukit/libblock/src/diskdevs.c                    |   14 +-
 cpukit/libcsupport/include/ringbuf.h              |   12 +-
 cpukit/libcsupport/include/rtems/libio_.h         |    6 +-
 cpukit/libcsupport/src/termios.c                  |   54 ++++----
 cpukit/posix/include/rtems/posix/psignalimpl.h    |    8 +-
 cpukit/posix/src/psignal.c                        |    8 +-
 cpukit/posix/src/psignalclearsignals.c            |    6 +-
 cpukit/posix/src/psignalsetprocesssignals.c       |    6 +-
 cpukit/posix/src/sigtimedwait.c                   |   10 +-
 cpukit/rtems/include/rtems/rtems/asrimpl.h        |   18 ++--
 cpukit/rtems/include/rtems/rtems/intr.h           |   31 +++--
 cpukit/rtems/src/clockgetuptimenanoseconds.c      |    6 +-
 cpukit/rtems/src/clockgetuptimeseconds.c          |    6 +-
 cpukit/sapi/src/chainsmp.c                        |   56 ++++----
 cpukit/score/include/rtems/score/isrlock.h        |  110 ++++++++++-------
 cpukit/score/include/rtems/score/percpu.h         |   78 +++++++++---
 cpukit/score/include/rtems/score/smplock.h        |  137 ++++++++++++++++-----
 cpukit/score/include/rtems/score/threaddispatch.h |    7 +-
 cpukit/score/include/rtems/score/todimpl.h        |    8 +-
 cpukit/score/src/coretodget.c                     |    6 +-
 cpukit/score/src/coretodsecondssinceepoch.c       |    6 +-
 cpukit/score/src/coretodset.c                     |    6 +-
 cpukit/score/src/coretodtickle.c                  |    6 +-
 cpukit/score/src/percpu.c                         |   22 +---
 cpukit/score/src/smp.c                            |    7 +-
 cpukit/score/src/threaddispatchdisablelevel.c     |   30 +++---
 cpukit/score/src/threadhandler.c                  |    6 +-
 testsuites/smptests/smplock01/init.c              |   25 +++--
 testsuites/sptests/sp37/init.c                    |   20 ++--
 testsuites/sptests/spcache01/init.c               |   47 ++++----
 testsuites/sptests/spnsext01/init.c               |    9 +-
 testsuites/tmtests/tmcontext01/init.c             |    6 +-
 33 files changed, 480 insertions(+), 329 deletions(-)

diff --git a/c/src/lib/libbsp/sparc/leon3/include/leon.h b/c/src/lib/libbsp/sparc/leon3/include/leon.h
index 00f158f..685b553 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/leon.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/leon.h
@@ -169,11 +169,11 @@ static __inline__ int bsp_irq_fixup(int irq)
 
 extern rtems_interrupt_lock LEON3_IrqCtrl_Lock;
 
-#define LEON3_IRQCTRL_ACQUIRE(_level ) \
-  rtems_interrupt_lock_acquire( &LEON3_IrqCtrl_Lock, _level )
+#define LEON3_IRQCTRL_ACQUIRE( _lock_context ) \
+  rtems_interrupt_lock_acquire( &LEON3_IrqCtrl_Lock, _lock_context )
 
-#define LEON3_IRQCTRL_RELEASE(_level ) \
-  rtems_interrupt_lock_release( &LEON3_IrqCtrl_Lock, _level )
+#define LEON3_IRQCTRL_RELEASE( _lock_context ) \
+  rtems_interrupt_lock_release( &LEON3_IrqCtrl_Lock, _lock_context )
 
 #define LEON_Clear_interrupt( _source ) \
   do { \
@@ -195,39 +195,39 @@ extern rtems_interrupt_lock LEON3_IrqCtrl_Lock;
 
 #define LEON_Mask_interrupt( _source ) \
   do { \
-    rtems_interrupt_level _level; \
-    LEON3_IRQCTRL_ACQUIRE( _level ); \
+    rtems_interrupt_lock_context _lock_context; \
+    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
      LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]  &= ~(1 << (_source)); \
-    LEON3_IRQCTRL_RELEASE( _level ); \
+    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
   } while (0)
 
 #define LEON_Unmask_interrupt( _source ) \
   do { \
-    rtems_interrupt_level _level; \
-    LEON3_IRQCTRL_ACQUIRE( _level ); \
+    rtems_interrupt_lock_context _lock_context; \
+    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
     LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]  |= (1 << (_source)); \
-    LEON3_IRQCTRL_RELEASE( _level ); \
+    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
   } while (0)
 
 #define LEON_Disable_interrupt( _source, _previous ) \
   do { \
-    rtems_interrupt_level _level; \
+    rtems_interrupt_lock_context _lock_context; \
     uint32_t _mask = 1 << (_source); \
-    LEON3_IRQCTRL_ACQUIRE( _level ); \
+    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
      (_previous) = LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index]; \
      LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = _previous & ~_mask; \
-    LEON3_IRQCTRL_RELEASE( _level ); \
+    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
     (_previous) &= _mask; \
   } while (0)
 
 #define LEON_Restore_interrupt( _source, _previous ) \
   do { \
-    rtems_interrupt_level _level; \
+    rtems_interrupt_lock_context _lock_context; \
     uint32_t _mask = 1 << (_source); \
-    LEON3_IRQCTRL_ACQUIRE( _level ); \
+    LEON3_IRQCTRL_ACQUIRE( &_lock_context ); \
       LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] = \
         (LEON3_IrqCtrl_Regs->mask[LEON3_Cpu_Index] & ~_mask) | (_previous); \
-    LEON3_IRQCTRL_RELEASE( _level ); \
+    LEON3_IRQCTRL_RELEASE( &_lock_context ); \
   } while (0)
 
 /* Make all SPARC BSPs have common macros for interrupt handling */
diff --git a/cpukit/libblock/src/diskdevs.c b/cpukit/libblock/src/diskdevs.c
index 79ed165..7e01ab3 100644
--- a/cpukit/libblock/src/diskdevs.c
+++ b/cpukit/libblock/src/diskdevs.c
@@ -435,15 +435,15 @@ rtems_disk_obtain(dev_t dev)
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
   rtems_disk_device *dd = NULL;
-  rtems_interrupt_level level;
+  rtems_interrupt_lock_context lock_context;
 
-  rtems_interrupt_lock_acquire(&diskdevs_lock, level);
+  rtems_interrupt_lock_acquire(&diskdevs_lock, &lock_context);
   if (!diskdevs_protected) {
     /* Frequent and quickest case */
     dd = get_disk_entry(dev, false);
-    rtems_interrupt_lock_release(&diskdevs_lock, level);
+    rtems_interrupt_lock_release(&diskdevs_lock, &lock_context);
   } else {
-    rtems_interrupt_lock_release(&diskdevs_lock, level);
+    rtems_interrupt_lock_release(&diskdevs_lock, &lock_context);
 
     sc = disk_lock();
     if (sc == RTEMS_SUCCESSFUL) {
@@ -458,15 +458,15 @@ rtems_disk_obtain(dev_t dev)
 rtems_status_code
 rtems_disk_release(rtems_disk_device *dd)
 {
-  rtems_interrupt_level level;
+  rtems_interrupt_lock_context lock_context;
   dev_t dev = dd->dev;
   unsigned uses = 0;
   bool deleted = false;
 
-  rtems_interrupt_lock_acquire(&diskdevs_lock, level);
+  rtems_interrupt_lock_acquire(&diskdevs_lock, &lock_context);
   uses = --dd->uses;
   deleted = dd->deleted;
-  rtems_interrupt_lock_release(&diskdevs_lock, level);
+  rtems_interrupt_lock_release(&diskdevs_lock, &lock_context);
 
   if (uses == 0 && deleted) {
     rtems_disk_delete(dev);
diff --git a/cpukit/libcsupport/include/ringbuf.h b/cpukit/libcsupport/include/ringbuf.h
index 13821a5..05bcceb 100644
--- a/cpukit/libcsupport/include/ringbuf.h
+++ b/cpukit/libcsupport/include/ringbuf.h
@@ -36,22 +36,22 @@ typedef struct {
 
 #define Ring_buffer_Add_character( _buffer, _ch ) \
   do { \
-    rtems_interrupt_level isrlevel; \
+    rtems_interrupt_lock_context lock_context; \
     \
-    rtems_interrupt_lock_acquire( &(_buffer)->lock, isrlevel ); \
+    rtems_interrupt_lock_acquire( &(_buffer)->lock, &lock_context ); \
       (_buffer)->tail = ((_buffer)->tail+1) % RINGBUF_QUEUE_LENGTH; \
       (_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
-    rtems_interrupt_lock_release( &(_buffer)->lock, isrlevel ); \
+    rtems_interrupt_lock_release( &(_buffer)->lock, &lock_context ); \
   } while ( 0 )
 
 #define Ring_buffer_Remove_character( _buffer, _ch ) \
   do { \
-    rtems_interrupt_level isrlevel; \
+    rtems_interrupt_lock_context lock_context; \
     \
-    rtems_interrupt_lock_acquire( &(_buffer)->lock, isrlevel ); \
+    rtems_interrupt_lock_acquire( &(_buffer)->lock, &lock_context ); \
       (_buffer)->head = ((_buffer)->head+1) % RINGBUF_QUEUE_LENGTH; \
       (_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
-    rtems_interrupt_lock_release( &(_buffer)->lock, isrlevel ); \
+    rtems_interrupt_lock_release( &(_buffer)->lock, &lock_context ); \
   } while ( 0 )
 
 #endif
diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h
index 78a57c8..c09e2b6 100644
--- a/cpukit/libcsupport/include/rtems/libio_.h
+++ b/cpukit/libcsupport/include/rtems/libio_.h
@@ -261,13 +261,13 @@ static inline void rtems_filesystem_mt_unlock( void )
 extern rtems_interrupt_lock rtems_filesystem_mt_entry_lock_control;
 
 #define rtems_filesystem_mt_entry_declare_lock_context( ctx ) \
-  rtems_interrupt_level ctx
+  rtems_interrupt_lock_context ctx
 
 #define rtems_filesystem_mt_entry_lock( ctx ) \
-  rtems_interrupt_lock_acquire( &rtems_filesystem_mt_entry_lock_control, ctx )
+  rtems_interrupt_lock_acquire( &rtems_filesystem_mt_entry_lock_control, &ctx )
 
 #define rtems_filesystem_mt_entry_unlock( ctx ) \
-  rtems_interrupt_lock_release( &rtems_filesystem_mt_entry_lock_control, ctx )
+  rtems_interrupt_lock_release( &rtems_filesystem_mt_entry_lock_control, &ctx )
 
 static inline void rtems_filesystem_instance_lock(
   const rtems_filesystem_location_info_t *loc
diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
index c462ce6..6c88de6 100644
--- a/cpukit/libcsupport/src/termios.c
+++ b/cpukit/libcsupport/src/termios.c
@@ -338,45 +338,45 @@ rtems_termios_open (
 static void
 drainOutput (struct rtems_termios_tty *tty)
 {
-  rtems_interrupt_level level;
+  rtems_interrupt_lock_context lock_context;
   rtems_status_code sc;
 
   if (tty->device.outputUsesInterrupts != TERMIOS_POLLED) {
-    rtems_termios_interrupt_lock_acquire (tty, level);
+    rtems_termios_interrupt_lock_acquire (tty, &lock_context);
     while (tty->rawOutBuf.Tail != tty->rawOutBuf.Head) {
       tty->rawOutBufState = rob_wait;
-      rtems_termios_interrupt_lock_release (tty, level);
+      rtems_termios_interrupt_lock_release (tty, &lock_context);
       sc = rtems_semaphore_obtain(
         tty->rawOutBuf.Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
       if (sc != RTEMS_SUCCESSFUL)
         rtems_fatal_error_occurred (sc);
-      rtems_termios_interrupt_lock_acquire (tty, level);
+      rtems_termios_interrupt_lock_acquire (tty, &lock_context);
     }
-    rtems_termios_interrupt_lock_release (tty, level);
+    rtems_termios_interrupt_lock_release (tty, &lock_context);
   }
 }
 
 static void
 flushOutput (struct rtems_termios_tty *tty)
 {
-  rtems_interrupt_level level;
+  rtems_interrupt_lock_context lock_context;
 
-  rtems_termios_interrupt_lock_acquire (tty, level);
+  rtems_termios_interrupt_lock_acquire (tty, &lock_context);
   tty->rawOutBuf.Tail = 0;
   tty->rawOutBuf.Head = 0;
   tty->rawOutBufState = rob_idle;
-  rtems_termios_interrupt_lock_release (tty, level);
+  rtems_termios_interrupt_lock_release (tty, &lock_context);
 }
 
 static void
 flushInput (struct rtems_termios_tty *tty)
 {
-  rtems_interrupt_level level;
+  rtems_interrupt_lock_context lock_context;
 
-  rtems_termios_interrupt_lock_acquire (tty, level);
+  rtems_termios_interrupt_lock_acquire (tty, &lock_context);
   tty->rawInBuf.Tail = 0;
   tty->rawInBuf.Head = 0;
-  rtems_termios_interrupt_lock_release (tty, level);
+  rtems_termios_interrupt_lock_release (tty, &lock_context);
 }
 
 rtems_status_code
@@ -469,7 +469,7 @@ rtems_status_code rtems_termios_bufsize (
 static void
 termios_set_flowctrl(struct rtems_termios_tty *tty)
 {
-  rtems_interrupt_level level;
+  rtems_interrupt_lock_context lock_context;
   /*
    * check for flow control options to be switched off
    */
@@ -483,7 +483,7 @@ termios_set_flowctrl(struct rtems_termios_tty *tty)
     /* has output been stopped due to received XOFF? */
     if (tty->flow_ctrl & FL_OSTOP) {
       /* disable interrupts    */
-      rtems_termios_interrupt_lock_acquire (tty, level);
+      rtems_termios_interrupt_lock_acquire (tty, &lock_context);
       tty->flow_ctrl &= ~FL_OSTOP;
       /* check for chars in output buffer (or rob_state?) */
       if (tty->rawOutBufState != rob_idle) {
@@ -492,7 +492,7 @@ termios_set_flowctrl(struct rtems_termios_tty *tty)
           tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
       }
       /* reenable interrupts */
-      rtems_termios_interrupt_lock_release (tty, level);
+      rtems_termios_interrupt_lock_release (tty, &lock_context);
     }
   }
   /* check for incoming XON/XOFF flow control switched off */
@@ -671,7 +671,7 @@ rtems_termios_puts (
 {
   const char *buf = _buf;
   unsigned int newHead;
-  rtems_interrupt_level level;
+  rtems_interrupt_lock_context lock_context;
   rtems_status_code sc;
 
   if (tty->device.outputUsesInterrupts == TERMIOS_POLLED) {
@@ -693,15 +693,15 @@ rtems_termios_puts (
      * with interrupts enabled.
      */
     newHead = (newHead + 1) % tty->rawOutBuf.Size;
-    rtems_termios_interrupt_lock_acquire (tty, level);
+    rtems_termios_interrupt_lock_acquire (tty, &lock_context);
     while (newHead == tty->rawOutBuf.Tail) {
       tty->rawOutBufState = rob_wait;
-      rtems_termios_interrupt_lock_release (tty, level);
+      rtems_termios_interrupt_lock_release (tty, &lock_context);
       sc = rtems_semaphore_obtain(
         tty->rawOutBuf.Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
       if (sc != RTEMS_SUCCESSFUL)
         rtems_fatal_error_occurred (sc);
-      rtems_termios_interrupt_lock_acquire (tty, level);
+      rtems_termios_interrupt_lock_acquire (tty, &lock_context);
     }
     tty->rawOutBuf.theBuf[tty->rawOutBuf.Head] = *buf++;
     tty->rawOutBuf.Head = newHead;
@@ -716,7 +716,7 @@ rtems_termios_puts (
       }
       tty->rawOutBufState = rob_busy;
     }
-    rtems_termios_interrupt_lock_release (tty, level);
+    rtems_termios_interrupt_lock_release (tty, &lock_context);
     len--;
   }
 }
@@ -1175,7 +1175,7 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
   char c;
   int dropped = 0;
   bool flow_rcv = false; /* true, if flow control char received */
-  rtems_interrupt_level level;
+  rtems_interrupt_lock_context lock_context;
 
   if (rtems_termios_linesw[tty->t_line].l_rint != NULL) {
     while (len--) {
@@ -1223,7 +1223,7 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
       /* restart output according to FL_ORCVXOF flag */
       if ((tty->flow_ctrl & (FL_ORCVXOF | FL_OSTOP)) == FL_OSTOP) {
         /* disable interrupts    */
-        rtems_termios_interrupt_lock_acquire (tty, level);
+        rtems_termios_interrupt_lock_acquire (tty, &lock_context);
         tty->flow_ctrl &= ~FL_OSTOP;
         /* check for chars in output buffer (or rob_state?) */
         if (tty->rawOutBufState != rob_idle) {
@@ -1232,12 +1232,12 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
             tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1);
         }
         /* reenable interrupts */
-        rtems_termios_interrupt_lock_release (tty, level);
+        rtems_termios_interrupt_lock_release (tty, &lock_context);
       }
     } else {
       newTail = (tty->rawInBuf.Tail + 1) % tty->rawInBuf.Size;
       /* if chars_in_buffer > highwater                */
-      rtems_termios_interrupt_lock_acquire (tty, level);
+      rtems_termios_interrupt_lock_acquire (tty, &lock_context);
       if ((((newTail - tty->rawInBuf.Head + tty->rawInBuf.Size)
             % tty->rawInBuf.Size) > tty->highwater) &&
           !(tty->flow_ctrl & FL_IREQXOF)) {
@@ -1263,7 +1263,7 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
       }
 
       /* reenable interrupts */
-      rtems_termios_interrupt_lock_release (tty, level);
+      rtems_termios_interrupt_lock_release (tty, &lock_context);
 
       if (newTail == tty->rawInBuf.Head) {
         dropped++;
@@ -1297,10 +1297,10 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
   bool wakeUpWriterTask = false;
   unsigned int newTail;
   int nToSend;
-  rtems_interrupt_level level;
+  rtems_interrupt_lock_context lock_context;
   int len;
 
-  rtems_termios_interrupt_lock_acquire (tty, level);
+  rtems_termios_interrupt_lock_acquire (tty, &lock_context);
 
   /* check for XOF/XON to send */
   if ((tty->flow_ctrl & (FL_MDXOF | FL_IREQXOF | FL_ISNTXOF))
@@ -1399,7 +1399,7 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
     tty->rawOutBuf.Tail = newTail; /*apm*/
   }
 
-  rtems_termios_interrupt_lock_release (tty, level);
+  rtems_termios_interrupt_lock_release (tty, &lock_context);
 
   if (wakeUpWriterTask) {
     rtems_semaphore_release (tty->rawOutBuf.Semaphore);
diff --git a/cpukit/posix/include/rtems/posix/psignalimpl.h b/cpukit/posix/include/rtems/posix/psignalimpl.h
index 9a493fd..d518e07 100644
--- a/cpukit/posix/include/rtems/posix/psignalimpl.h
+++ b/cpukit/posix/include/rtems/posix/psignalimpl.h
@@ -80,11 +80,11 @@ extern API_extensions_Post_switch_control _POSIX_signals_Post_switch;
  */
 void _POSIX_signals_Manager_Initialization(void);
 
-#define _POSIX_signals_Acquire( level ) \
-  _ISR_lock_ISR_disable_and_acquire( &_POSIX_signals_Lock, level )
+#define _POSIX_signals_Acquire( lock_context ) \
+  _ISR_lock_ISR_disable_and_acquire( &_POSIX_signals_Lock, lock_context )
 
-#define _POSIX_signals_Release( level ) \
-  _ISR_lock_Release_and_ISR_enable( &_POSIX_signals_Lock, level )
+#define _POSIX_signals_Release( lock_context ) \
+  _ISR_lock_Release_and_ISR_enable( &_POSIX_signals_Lock, lock_context )
 
 static inline void _POSIX_signals_Add_post_switch_extension(void)
 {
diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c
index 5258b2b..fbe96b3 100644
--- a/cpukit/posix/src/psignal.c
+++ b/cpukit/posix/src/psignal.c
@@ -118,7 +118,7 @@ static void _POSIX_signals_Post_switch_hook(
 {
   POSIX_API_Control  *api;
   int                 signo;
-  ISR_Level           level;
+  ISR_lock_Context    lock_context;
   int                 hold_errno;
   Thread_Control     *executing;
 
@@ -146,13 +146,13 @@ static void _POSIX_signals_Post_switch_hook(
    *  processed at all.  No point in doing this loop otherwise.
    */
   while (1) {
-    _POSIX_signals_Acquire( level );
+    _POSIX_signals_Acquire( &lock_context );
       if ( !(~api->signals_blocked &
             (api->signals_pending | _POSIX_signals_Pending)) ) {
-       _POSIX_signals_Release( level );
+       _POSIX_signals_Release( &lock_context );
        break;
      }
-    _POSIX_signals_Release( level );
+    _POSIX_signals_Release( &lock_context );
 
     for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
       _POSIX_signals_Check_signal( api, signo, false );
diff --git a/cpukit/posix/src/psignalclearsignals.c b/cpukit/posix/src/psignalclearsignals.c
index 88de41c..4154847 100644
--- a/cpukit/posix/src/psignalclearsignals.c
+++ b/cpukit/posix/src/psignalclearsignals.c
@@ -48,7 +48,7 @@ bool _POSIX_signals_Clear_signals(
 {
   sigset_t                    mask;
   sigset_t                    signals_blocked;
-  ISR_Level                   level;
+  ISR_lock_Context            lock_context;
   bool                        do_callout;
   POSIX_signals_Siginfo_node *psiginfo;
 
@@ -69,7 +69,7 @@ bool _POSIX_signals_Clear_signals(
   /* XXX are we sure they can be cleared the same way? */
 
   if ( do_signals_acquire_release ) {
-    _POSIX_signals_Acquire( level );
+    _POSIX_signals_Acquire( &lock_context );
   }
 
     if ( is_global ) {
@@ -103,7 +103,7 @@ bool _POSIX_signals_Clear_signals(
     }
 
   if ( do_signals_acquire_release ) {
-    _POSIX_signals_Release( level );
+    _POSIX_signals_Release( &lock_context );
   }
 
   return do_callout;
diff --git a/cpukit/posix/src/psignalsetprocesssignals.c b/cpukit/posix/src/psignalsetprocesssignals.c
index 9cce233..4057b14 100644
--- a/cpukit/posix/src/psignalsetprocesssignals.c
+++ b/cpukit/posix/src/psignalsetprocesssignals.c
@@ -37,9 +37,9 @@ void _POSIX_signals_Set_process_signals(
   sigset_t   mask
 )
 {
-  ISR_Level  level;
+  ISR_lock_Context lock_context;
 
-  _POSIX_signals_Acquire( level );
+  _POSIX_signals_Acquire( &lock_context );
     _POSIX_signals_Pending |= mask;
-  _POSIX_signals_Release( level );
+  _POSIX_signals_Release( &lock_context );
 }
diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c
index 2f1f2cc..efd215a 100644
--- a/cpukit/posix/src/sigtimedwait.c
+++ b/cpukit/posix/src/sigtimedwait.c
@@ -78,7 +78,7 @@ int sigtimedwait(
   siginfo_t          signal_information;
   siginfo_t         *the_info;
   int                signo;
-  ISR_Level          level;
+  ISR_lock_Context   lock_context;
 
   /*
    *  Error check parameters before disabling interrupts.
@@ -117,7 +117,7 @@ int sigtimedwait(
 
   /* API signals pending? */
 
-  _POSIX_signals_Acquire( level );
+  _POSIX_signals_Acquire( &lock_context );
   if ( *set & api->signals_pending ) {
     /* XXX real info later */
     the_info->si_signo = _POSIX_signals_Get_lowest( api->signals_pending );
@@ -129,7 +129,7 @@ int sigtimedwait(
       false,
       false
     );
-    _POSIX_signals_Release( level );
+    _POSIX_signals_Release( &lock_context );
 
     the_info->si_code = SI_USER;
     the_info->si_value.sival_int = 0;
@@ -141,7 +141,7 @@ int sigtimedwait(
   if ( *set & _POSIX_signals_Pending ) {
     signo = _POSIX_signals_Get_lowest( _POSIX_signals_Pending );
     _POSIX_signals_Clear_signals( api, signo, the_info, true, false, false );
-    _POSIX_signals_Release( level );
+    _POSIX_signals_Release( &lock_context );
 
     the_info->si_signo = signo;
     the_info->si_code = SI_USER;
@@ -157,7 +157,7 @@ int sigtimedwait(
     executing->Wait.option          = *set;
     executing->Wait.return_argument = the_info;
     _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
-    _POSIX_signals_Release( level );
+    _POSIX_signals_Release( &lock_context );
     _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, executing, interval );
   _Thread_Enable_dispatch();
 
diff --git a/cpukit/rtems/include/rtems/rtems/asrimpl.h b/cpukit/rtems/include/rtems/rtems/asrimpl.h
index ebb4052..d67198f 100644
--- a/cpukit/rtems/include/rtems/rtems/asrimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/asrimpl.h
@@ -61,13 +61,13 @@ RTEMS_INLINE_ROUTINE void _ASR_Swap_signals (
 )
 {
   rtems_signal_set _signals;
-  ISR_Level        _level;
+  ISR_lock_Context lock_context;
 
-  _ISR_lock_ISR_disable_and_acquire( &asr->Lock, _level );
+  _ISR_lock_ISR_disable_and_acquire( &asr->Lock, &lock_context );
     _signals             = asr->signals_pending;
     asr->signals_pending = asr->signals_posted;
     asr->signals_posted  = _signals;
-  _ISR_lock_Release_and_ISR_enable( &asr->Lock, _level );
+  _ISR_lock_Release_and_ISR_enable( &asr->Lock, &lock_context );
 }
 
 /**
@@ -110,11 +110,11 @@ RTEMS_INLINE_ROUTINE void _ASR_Post_signals(
   rtems_signal_set *signal_set
 )
 {
-  ISR_Level              _level;
+  ISR_lock_Context lock_context;
 
-  _ISR_lock_ISR_disable_and_acquire( &asr->Lock, _level );
+  _ISR_lock_ISR_disable_and_acquire( &asr->Lock, &lock_context );
     *signal_set |= signals;
-  _ISR_lock_Release_and_ISR_enable( &asr->Lock, _level );
+  _ISR_lock_Release_and_ISR_enable( &asr->Lock, &lock_context );
 }
 
 RTEMS_INLINE_ROUTINE rtems_signal_set _ASR_Get_posted_signals(
@@ -122,12 +122,12 @@ RTEMS_INLINE_ROUTINE rtems_signal_set _ASR_Get_posted_signals(
 )
 {
   rtems_signal_set signal_set;
-  ISR_Level        _level;
+  ISR_lock_Context lock_context;
 
-  _ISR_lock_ISR_disable_and_acquire( &asr->Lock, _level );
+  _ISR_lock_ISR_disable_and_acquire( &asr->Lock, &lock_context );
     signal_set = asr->signals_posted;
     asr->signals_posted = 0;
-  _ISR_lock_Release_and_ISR_enable( &asr->Lock, _level );
+  _ISR_lock_Release_and_ISR_enable( &asr->Lock, &lock_context );
 
   return signal_set;
 }
diff --git a/cpukit/rtems/include/rtems/rtems/intr.h b/cpukit/rtems/include/rtems/rtems/intr.h
index a98d0be..62d2dad 100644
--- a/cpukit/rtems/include/rtems/rtems/intr.h
+++ b/cpukit/rtems/include/rtems/rtems/intr.h
@@ -160,6 +160,11 @@ rtems_status_code rtems_interrupt_catch(
 typedef ISR_lock_Control rtems_interrupt_lock;
 
 /**
+ * @brief Local interrupt lock context for acquire and release pairs.
+ */
+typedef ISR_lock_Context rtems_interrupt_lock_context;
+
+/**
  * @brief Initializer for static initialization of interrupt locks.
  */
 #define RTEMS_INTERRUPT_LOCK_INITIALIZER ISR_LOCK_INITIALIZER
@@ -183,12 +188,13 @@ typedef ISR_lock_Control rtems_interrupt_lock;
  * This function can be used in thread and interrupt context.
  *
  * @param[in,out] _lock The interrupt lock.
- * @param[out] _isr_cookie The interrupt status to restore will be returned.
+ * @param[in,out] _lock_context The local interrupt lock context for an acquire
+ * and release pair.
  *
  * @see rtems_interrupt_lock_release().
  */
-#define rtems_interrupt_lock_acquire( _lock, _isr_cookie ) \
-  _ISR_lock_ISR_disable_and_acquire( _lock, _isr_cookie )
+#define rtems_interrupt_lock_acquire( _lock, _lock_context ) \
+  _ISR_lock_ISR_disable_and_acquire( _lock, _lock_context )
 
 /**
  * @brief Releases an interrupt lock.
@@ -199,12 +205,13 @@ typedef ISR_lock_Control rtems_interrupt_lock;
  * This function can be used in thread and interrupt context.
  *
  * @param[in,out] _lock The interrupt lock.
- * @param[in] _isr_cookie The interrupt status to restore.
+ * @param[in,out] _lock_context The local interrupt lock context for an acquire
+ * and release pair.
  *
  * @see rtems_interrupt_lock_acquire().
  */
-#define rtems_interrupt_lock_release( _lock, _isr_cookie ) \
-  _ISR_lock_Release_and_ISR_enable( _lock, _isr_cookie )
+#define rtems_interrupt_lock_release( _lock, _lock_context ) \
+  _ISR_lock_Release_and_ISR_enable( _lock, _lock_context )
 
 /**
  * @brief Acquires an interrupt lock in the corresponding interrupt service
@@ -218,11 +225,13 @@ typedef ISR_lock_Control rtems_interrupt_lock;
  * protected by this lock, then the result is unpredictable.
  *
  * @param[in,out] _lock The interrupt lock.
+ * @param[in,out] _lock_context The local interrupt lock context for an acquire
+ * and release pair.
  *
  * @see rtems_interrupt_lock_release_isr().
  */
-#define rtems_interrupt_lock_acquire_isr( _lock ) \
-  _ISR_lock_Acquire( _lock )
+#define rtems_interrupt_lock_acquire_isr( _lock, _lock_context ) \
+  _ISR_lock_Acquire( _lock, _lock_context )
 
 /**
  * @brief Releases an interrupt lock in the corresponding interrupt service
@@ -232,11 +241,13 @@ typedef ISR_lock_Control rtems_interrupt_lock;
  * function releases an SMP lock.
  *
  * @param[in,out] _lock The interrupt lock.
+ * @param[in,out] _lock_context The local interrupt lock context for an acquire
+ * and release pair.
  *
  * @see rtems_interrupt_lock_acquire_isr().
  */
-#define rtems_interrupt_lock_release_isr( _lock ) \
-  _ISR_lock_Release( _lock )
+#define rtems_interrupt_lock_release_isr( _lock, _lock_context ) \
+  _ISR_lock_Release( _lock, _lock_context )
 
 /** @} */
 
diff --git a/cpukit/rtems/src/clockgetuptimenanoseconds.c b/cpukit/rtems/src/clockgetuptimenanoseconds.c
index c07a430..4777565 100644
--- a/cpukit/rtems/src/clockgetuptimenanoseconds.c
+++ b/cpukit/rtems/src/clockgetuptimenanoseconds.c
@@ -24,12 +24,12 @@ uint64_t rtems_clock_get_uptime_nanoseconds( void )
 {
   Timestamp_Control  snapshot_as_timestamp;
   uint32_t           nanoseconds;
-  ISR_Level          level;
+  ISR_lock_Context   lock_context;
 
-  _TOD_Acquire( &_TOD, level );
+  _TOD_Acquire( &_TOD, &lock_context );
     snapshot_as_timestamp = _TOD.uptime;
     nanoseconds = ( *_TOD.nanoseconds_since_last_tick )();
-  _TOD_Release( &_TOD, level );
+  _TOD_Release( &_TOD, &lock_context );
 
   return _Timestamp_Get_As_nanoseconds( &snapshot_as_timestamp, nanoseconds );
 }
diff --git a/cpukit/rtems/src/clockgetuptimeseconds.c b/cpukit/rtems/src/clockgetuptimeseconds.c
index 3b597ac..ce4b8a5 100644
--- a/cpukit/rtems/src/clockgetuptimeseconds.c
+++ b/cpukit/rtems/src/clockgetuptimeseconds.c
@@ -31,11 +31,11 @@ time_t rtems_clock_get_uptime_seconds( void )
   TOD_Control       *tod = &_TOD;
   Timestamp_Control  snapshot_as_timestamp;
   struct timespec    snapshot_as_timespec;
-  ISR_Level          level;
+  ISR_lock_Context   lock_context;
 
-  _TOD_Acquire( tod, level );
+  _TOD_Acquire( tod, &lock_context );
   snapshot_as_timestamp = tod->uptime;
-  _TOD_Release( tod, level );
+  _TOD_Release( tod, &lock_context );
 
   _Timestamp_To_timespec( &snapshot_as_timestamp, &snapshot_as_timespec );
 
diff --git a/cpukit/sapi/src/chainsmp.c b/cpukit/sapi/src/chainsmp.c
index 5554860..3f041ba 100644
--- a/cpukit/sapi/src/chainsmp.c
+++ b/cpukit/sapi/src/chainsmp.c
@@ -24,44 +24,44 @@
 
 static SMP_lock_Control chain_lock = SMP_LOCK_INITIALIZER;
 
-static void chain_acquire( ISR_Level *level )
+static void chain_acquire( SMP_lock_Context *lock_context )
 {
-  _SMP_lock_ISR_disable_and_acquire( &chain_lock, *level );
+  _SMP_lock_ISR_disable_and_acquire( &chain_lock, lock_context );
 }
 
-static void chain_release( ISR_Level *level )
+static void chain_release( SMP_lock_Context *lock_context )
 {
-  _SMP_lock_Release_and_ISR_enable( &chain_lock, *level );
+  _SMP_lock_Release_and_ISR_enable( &chain_lock, lock_context );
 }
 
 void rtems_chain_extract( rtems_chain_node *node )
 {
-  ISR_Level level;
+  SMP_lock_Context lock_context;
 
-  chain_acquire( &level );
+  chain_acquire( &lock_context );
   _Chain_Extract_unprotected( node );
-  chain_release( &level );
+  chain_release( &lock_context );
 }
 
 rtems_chain_node *rtems_chain_get( rtems_chain_control *chain )
 {
   rtems_chain_node *node;
-  ISR_Level level;
+  SMP_lock_Context lock_context;
 
-  chain_acquire( &level );
+  chain_acquire( &lock_context );
   node = _Chain_Get_unprotected( chain );
-  chain_release( &level );
+  chain_release( &lock_context );
 
   return node;
 }
 
 void rtems_chain_insert( rtems_chain_node *after_node, rtems_chain_node *node )
 {
-  ISR_Level level;
+  SMP_lock_Context lock_context;
 
-  chain_acquire( &level );
+  chain_acquire( &lock_context );
   _Chain_Insert_unprotected( after_node, node );
-  chain_release( &level );
+  chain_release( &lock_context );
 }
 
 void rtems_chain_append(
@@ -69,11 +69,11 @@ void rtems_chain_append(
   rtems_chain_node *node
 )
 {
-  ISR_Level level;
+  SMP_lock_Context lock_context;
 
-  chain_acquire( &level );
+  chain_acquire( &lock_context );
   _Chain_Append_unprotected( chain, node );
-  chain_release( &level );
+  chain_release( &lock_context );
 }
 
 void rtems_chain_prepend(
@@ -81,11 +81,11 @@ void rtems_chain_prepend(
   rtems_chain_node *node
 )
 {
-  ISR_Level level;
+  SMP_lock_Context lock_context;
 
-  chain_acquire( &level );
+  chain_acquire( &lock_context );
   _Chain_Prepend_unprotected( chain, node );
-  chain_release( &level );
+  chain_release( &lock_context );
 }
 
 bool rtems_chain_append_with_empty_check(
@@ -94,11 +94,11 @@ bool rtems_chain_append_with_empty_check(
 )
 {
   bool was_empty;
-  ISR_Level level;
+  SMP_lock_Context lock_context;
 
-  chain_acquire( &level );
+  chain_acquire( &lock_context );
   was_empty = _Chain_Append_with_empty_check_unprotected( chain, node );
-  chain_release( &level );
+  chain_release( &lock_context );
 
   return was_empty;
 }
@@ -109,11 +109,11 @@ bool rtems_chain_prepend_with_empty_check(
 )
 {
   bool was_empty;
-  ISR_Level level;
+  SMP_lock_Context lock_context;
 
-  chain_acquire( &level );
+  chain_acquire( &lock_context );
   was_empty = _Chain_Prepend_with_empty_check_unprotected( chain, node );
-  chain_release( &level );
+  chain_release( &lock_context );
 
   return was_empty;
 }
@@ -124,11 +124,11 @@ bool rtems_chain_get_with_empty_check(
 )
 {
   bool is_empty_now;
-  ISR_Level level;
+  SMP_lock_Context lock_context;
 
-  chain_acquire( &level );
+  chain_acquire( &lock_context );
   is_empty_now = _Chain_Get_with_empty_check_unprotected( chain, node );
-  chain_release( &level );
+  chain_release( &lock_context );
 
   return is_empty_now;
 }
diff --git a/cpukit/score/include/rtems/score/isrlock.h b/cpukit/score/include/rtems/score/isrlock.h
index 56ff19b..e118475 100644
--- a/cpukit/score/include/rtems/score/isrlock.h
+++ b/cpukit/score/include/rtems/score/isrlock.h
@@ -51,12 +51,23 @@ extern "C" {
  * @brief ISR lock control.
  */
 typedef struct {
-  #if defined( RTEMS_SMP )
-    SMP_lock_Control lock;
-  #endif
+#if defined( RTEMS_SMP )
+  SMP_lock_Control lock;
+#endif
 } ISR_lock_Control;
 
 /**
+ * @brief Local ISR lock context for acquire and release pairs.
+ */
+typedef struct {
+#if defined( RTEMS_SMP )
+  SMP_lock_Context lock_context;
+#else
+  ISR_Level isr_level;
+#endif
+} ISR_lock_Context;
+
+/**
  * @brief Initializer for static initialization of ISR locks.
  */
 #if defined( RTEMS_SMP )
@@ -72,17 +83,16 @@ typedef struct {
  *
  * Concurrent initialization leads to unpredictable results.
  *
- * @param[in,out] _lock The ISR lock control.
+ * @param[in,out] lock The ISR lock control.
  */
+static inline void _ISR_lock_Initialize( ISR_lock_Control *lock )
+{
 #if defined( RTEMS_SMP )
-  #define _ISR_lock_Initialize( _lock ) \
-    _SMP_lock_Initialize( &( _lock )->lock )
+  _SMP_lock_Initialize( &lock->lock );
 #else
-  #define _ISR_lock_Initialize( _lock ) \
-    do { \
-      (void) _lock; \
-    } while (0)
+  (void) lock;
 #endif
+}
 
 /**
  * @brief Acquires an ISR lock.
@@ -92,21 +102,24 @@ typedef struct {
  *
  * This function can be used in thread and interrupt context.
  *
- * @param[in,out] _lock The ISR lock control.
- * @param[out] _isr_cookie The interrupt status to restore will be returned.
+ * @param[in,out] lock The ISR lock control.
+ * @param[in,out] context The local ISR lock context for an acquire and release
+ * pair.
  *
  * @see _ISR_lock_Release_and_ISR_enable().
  */
+static inline void _ISR_lock_ISR_disable_and_acquire(
+  ISR_lock_Control *lock,
+  ISR_lock_Context *context
+)
+{
 #if defined( RTEMS_SMP )
-  #define _ISR_lock_ISR_disable_and_acquire( _lock, _isr_cookie ) \
-    _SMP_lock_ISR_disable_and_acquire( &( _lock )->lock, _isr_cookie )
+  _SMP_lock_ISR_disable_and_acquire( &lock->lock, &context->lock_context );
 #else
-  #define _ISR_lock_ISR_disable_and_acquire( _lock, _isr_cookie ) \
-    do { \
-      (void) _lock; \
-      _ISR_Disable( _isr_cookie ); \
-    } while (0)
+  (void) lock;
+  _ISR_Disable( context->isr_level );
 #endif
+}
 
 /**
  * @brief Releases an ISR lock.
@@ -116,21 +129,24 @@ typedef struct {
  *
  * This function can be used in thread and interrupt context.
  *
- * @param[in,out] _lock The ISR lock control.
- * @param[in] _isr_cookie The interrupt status to restore.
+ * @param[in,out] lock The ISR lock control.
+ * @param[in,out] context The local ISR lock context for an acquire and release
+ * pair.
  *
  * @see _ISR_lock_ISR_disable_and_acquire().
  */
+static inline void _ISR_lock_Release_and_ISR_enable(
+  ISR_lock_Control *lock,
+  ISR_lock_Context *context
+)
+{
 #if defined( RTEMS_SMP )
-  #define _ISR_lock_Release_and_ISR_enable( _lock, _isr_cookie ) \
-    _SMP_lock_Release_and_ISR_enable( &( _lock )->lock, _isr_cookie )
+  _SMP_lock_Release_and_ISR_enable( &lock->lock, &context->lock_context );
 #else
-  #define _ISR_lock_Release_and_ISR_enable( _lock, _isr_cookie ) \
-    do { \
-      (void) _lock; \
-      _ISR_Enable( _isr_cookie ); \
-    } while (0)
+  (void) lock;
+  _ISR_Enable( context->isr_level );
 #endif
+}
 
 /**
  * @brief Acquires an ISR lock inside an ISR disabled section.
@@ -142,19 +158,24 @@ typedef struct {
  * interrupts and these interrupts enter the critical section protected by this
  * lock, then the result is unpredictable.
  *
- * @param[in,out] _lock The ISR lock control.
+ * @param[in,out] lock The ISR lock control.
+ * @param[in,out] context The local ISR lock context for an acquire and release
+ * pair.
  *
  * @see _ISR_lock_Release().
  */
+static inline void _ISR_lock_Acquire(
+  ISR_lock_Control *lock,
+  ISR_lock_Context *context
+)
+{
 #if defined( RTEMS_SMP )
-  #define _ISR_lock_Acquire( _lock ) \
-    _SMP_lock_Acquire( &( _lock )->lock )
+  _SMP_lock_Acquire( &lock->lock, &context->lock_context );
 #else
-  #define _ISR_lock_Acquire( _lock ) \
-    do { \
-      (void) _lock; \
-    } while (0)
+  (void) lock;
+  (void) context;
 #endif
+}
 
 /**
  * @brief Releases an ISR lock inside an ISR disabled section.
@@ -162,19 +183,24 @@ typedef struct {
  * The interrupt status will remain unchanged.  On SMP configurations this
  * function releases an SMP lock.
  *
- * @param[in,out] _lock The ISR lock control.
+ * @param[in,out] lock The ISR lock control.
+ * @param[in,out] context The local ISR lock context for an acquire and release
+ * pair.
  *
  * @see _ISR_lock_Acquire().
  */
+static inline void _ISR_lock_Release(
+  ISR_lock_Control *lock,
+  ISR_lock_Context *context
+)
+{
 #if defined( RTEMS_SMP )
-  #define _ISR_lock_Release( _lock ) \
-    _SMP_lock_Release( &( _lock )->lock )
+  _SMP_lock_Release( &lock->lock, &context->lock_context );
 #else
-  #define _ISR_lock_Release( _lock ) \
-    do { \
-      (void) _lock; \
-    } while (0)
+  (void) lock;
+  (void) context;
 #endif
+}
 
 /** @} */
 
diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h
index 4b7fd62..067cb84 100644
--- a/cpukit/score/include/rtems/score/percpu.h
+++ b/cpukit/score/include/rtems/score/percpu.h
@@ -23,9 +23,10 @@
   #include <rtems/asm.h>
 #else
   #include <rtems/score/assert.h>
-  #include <rtems/score/isrlock.h>
-  #include <rtems/score/timestamp.h>
+  #include <rtems/score/isrlevel.h>
   #include <rtems/score/smp.h>
+  #include <rtems/score/smplock.h>
+  #include <rtems/score/timestamp.h>
 #endif
 
 #ifdef __cplusplus
@@ -203,14 +204,23 @@ typedef struct {
   /** This is the time of the last context switch on this CPU. */
   Timestamp_Control time_of_last_context_switch;
 
-  /**
-   * @brief This lock protects the dispatch_necessary, executing, heir and
-   * message fields.
-   */
-  ISR_lock_Control lock;
-
   #if defined( RTEMS_SMP )
     /**
+     * @brief This lock protects the dispatch_necessary, executing, heir and
+     * message fields.
+     *
+     * We must use a ticket lock here since we cannot transport a local context
+     * through the context switch.
+     */
+    SMP_ticket_lock_Control Lock;
+
+    /**
+     * @brief Context for the Giant lock acquire and release pair of this
+     * processor.
+     */
+    SMP_lock_Context Giant_lock_context;
+
+    /**
      *  This is the request for the interrupt.
      *
      *  @note This may become a chain protected by atomic instructions.
@@ -247,17 +257,53 @@ typedef struct {
  */
 extern Per_CPU_Control_envelope _Per_CPU_Information[] CPU_STRUCTURE_ALIGNMENT;
 
-#define _Per_CPU_ISR_disable_and_acquire( per_cpu, isr_cookie ) \
-  _ISR_lock_ISR_disable_and_acquire( &( per_cpu )->lock, isr_cookie )
-
-#define _Per_CPU_Release_and_ISR_enable( per_cpu, isr_cookie ) \
-  _ISR_lock_Release_and_ISR_enable( &( per_cpu )->lock, isr_cookie )
-
+#if defined( RTEMS_SMP )
+#define _Per_CPU_Acquire( per_cpu ) \
+  _SMP_ticket_lock_Acquire( &( per_cpu )->Lock )
+#else
 #define _Per_CPU_Acquire( per_cpu ) \
-  _ISR_lock_Acquire( &( per_cpu )->lock )
+  do { \
+    (void) ( per_cpu ); \
+  } while ( 0 )
+#endif
 
+#if defined( RTEMS_SMP )
+#define _Per_CPU_Release( per_cpu ) \
+  _SMP_ticket_lock_Release( &( per_cpu )->Lock )
+#else
 #define _Per_CPU_Release( per_cpu ) \
-  _ISR_lock_Release( &( per_cpu )->lock )
+  do { \
+    (void) ( per_cpu ); \
+  } while ( 0 )
+#endif
+
+#if defined( RTEMS_SMP )
+#define _Per_CPU_ISR_disable_and_acquire( per_cpu, isr_cookie ) \
+  do { \
+    _ISR_Disable_without_giant( isr_cookie ); \
+    _Per_CPU_Acquire( per_cpu ); \
+  } while ( 0 )
+#else
+#define _Per_CPU_ISR_disable_and_acquire( per_cpu, isr_cookie ) \
+  do { \
+    _ISR_Disable( isr_cookie ); \
+    (void) ( per_cpu ); \
+  } while ( 0 )
+#endif
+
+#if defined( RTEMS_SMP )
+#define _Per_CPU_Release_and_ISR_enable( per_cpu, isr_cookie ) \
+  do { \
+    _Per_CPU_Release( per_cpu ); \
+    _ISR_Enable_without_giant( isr_cookie ); \
+  } while ( 0 )
+#else
+#define _Per_CPU_Release_and_ISR_enable( per_cpu, isr_cookie ) \
+  do { \
+    (void) ( per_cpu ); \
+    _ISR_Enable( isr_cookie ); \
+  } while ( 0 )
+#endif
 
 #if defined( RTEMS_SMP )
 #define _Per_CPU_Acquire_all( isr_cookie ) \
diff --git a/cpukit/score/include/rtems/score/smplock.h b/cpukit/score/include/rtems/score/smplock.h
index 25efbfa..101aa0a 100644
--- a/cpukit/score/include/rtems/score/smplock.h
+++ b/cpukit/score/include/rtems/score/smplock.h
@@ -42,54 +42,50 @@ extern "C" {
  * The SMP lock is implemented as a ticket lock.  This provides fairness in
  * case of concurrent lock attempts.
  *
- * This SMP lock API has a flaw.  It does not provide the ability to use a
- * local context for acquire and release pairs.  Such a context is necessary to
- * implement for example the Mellor-Crummey and Scott (MCS) locks.  The SMP
- * lock is currently used in _Thread_Disable_dispatch() and
- * _Thread_Enable_dispatch() and makes them to a giant lock acquire and
- * release.  Since these functions do not pass state information via a local
- * context there is currently no use case for such a feature.
+ * This SMP lock API uses a local context for acquire and release pairs.  Such
+ * a context may be used to implement for example the Mellor-Crummey and Scott
+ * (MCS) locks in the future.
  *
  * @{
  */
 
 /**
- * @brief SMP lock control.
+ * @brief SMP ticket lock control.
  */
 typedef struct {
   Atomic_Uint next_ticket;
   Atomic_Uint now_serving;
-} SMP_lock_Control;
+} SMP_ticket_lock_Control;
 
 /**
- * @brief SMP lock control initializer for static initialization.
+ * @brief SMP ticket lock control initializer for static initialization.
  */
-#define SMP_LOCK_INITIALIZER \
+#define SMP_TICKET_LOCK_INITIALIZER \
   { ATOMIC_INITIALIZER_UINT( 0U ), ATOMIC_INITIALIZER_UINT( 0U ) }
 
 /**
- * @brief Initializes a SMP lock control.
+ * @brief Initializes an SMP ticket lock control.
  *
  * Concurrent initialization leads to unpredictable results.
  *
- * @param[out] lock The SMP lock control.
+ * @param[out] lock The SMP ticket lock control.
  */
-static inline void _SMP_lock_Initialize( SMP_lock_Control *lock )
+static inline void _SMP_ticket_lock_Initialize( SMP_ticket_lock_Control *lock )
 {
   _Atomic_Init_uint( &lock->next_ticket, 0U );
   _Atomic_Init_uint( &lock->now_serving, 0U );
 }
 
 /**
- * @brief Acquires a SMP lock.
+ * @brief Acquires an SMP ticket lock.
  *
  * This function will not disable interrupts.  The caller must ensure that the
  * current thread of execution is not interrupted indefinite once it obtained
- * the SMP lock.
+ * the SMP ticket lock.
  *
- * @param[in,out] lock The SMP lock control.
+ * @param[in,out] lock The SMP ticket lock control.
  */
-static inline void _SMP_lock_Acquire( SMP_lock_Control *lock )
+static inline void _SMP_ticket_lock_Acquire( SMP_ticket_lock_Control *lock )
 {
   unsigned int my_ticket =
     _Atomic_Fetch_add_uint( &lock->next_ticket, 1U, ATOMIC_ORDER_RELAXED );
@@ -102,11 +98,11 @@ static inline void _SMP_lock_Acquire( SMP_lock_Control *lock )
 }
 
 /**
- * @brief Releases a SMP lock.
+ * @brief Releases an SMP ticket lock.
  *
- * @param[in,out] lock The SMP lock control.
+ * @param[in,out] lock The SMP ticket lock control.
  */
-static inline void _SMP_lock_Release( SMP_lock_Control *lock )
+static inline void _SMP_ticket_lock_Release( SMP_ticket_lock_Control *lock )
 {
   unsigned int current_ticket =
     _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED );
@@ -116,28 +112,103 @@ static inline void _SMP_lock_Release( SMP_lock_Control *lock )
 }
 
 /**
+ * @brief SMP lock control.
+ */
+typedef struct {
+  SMP_ticket_lock_Control ticket_lock;
+} SMP_lock_Control;
+
+/**
+ * @brief Local SMP lock context for acquire and release pairs.
+ */
+typedef struct {
+  ISR_Level isr_level;
+} SMP_lock_Context;
+
+/**
+ * @brief SMP lock control initializer for static initialization.
+ */
+#define SMP_LOCK_INITIALIZER { SMP_TICKET_LOCK_INITIALIZER }
+
+/**
+ * @brief Initializes an SMP lock control.
+ *
+ * Concurrent initialization leads to unpredictable results.
+ *
+ * @param[out] lock The SMP lock control.
+ */
+static inline void _SMP_lock_Initialize( SMP_lock_Control *lock )
+{
+  _SMP_ticket_lock_Initialize( &lock->ticket_lock );
+}
+
+/**
+ * @brief Acquires an SMP lock.
+ *
+ * This function will not disable interrupts.  The caller must ensure that the
+ * current thread of execution is not interrupted indefinite once it obtained
+ * the SMP lock.
+ *
+ * @param[in,out] lock The SMP lock control.
+ * @param[in,out] context The local SMP lock context for an acquire and release
+ * pair.
+ */
+static inline void _SMP_lock_Acquire(
+  SMP_lock_Control *lock,
+  SMP_lock_Context *context
+)
+{
+  (void) context;
+  _SMP_ticket_lock_Acquire( &lock->ticket_lock );
+}
+
+/**
+ * @brief Releases an SMP lock.
+ *
+ * @param[in,out] lock The SMP lock control.
+ * @param[in,out] context The local SMP lock context for an acquire and release
+ * pair.
+ */
+static inline void _SMP_lock_Release(
+  SMP_lock_Control *lock,
+  SMP_lock_Context *context
+)
+{
+  (void) context;
+  _SMP_ticket_lock_Release( &lock->ticket_lock );
+}
+
+/**
  * @brief Disables interrupts and acquires the SMP lock.
  *
  * @param[in,out] lock The SMP lock control.
- * @param[out] isr_cookie The ISR cookie.
+ * @param[in,out] context The local SMP lock context for an acquire and release
+ * pair.
  */
-#define _SMP_lock_ISR_disable_and_acquire( lock, isr_cookie ) \
-  do { \
-    _ISR_Disable_without_giant( isr_cookie ); \
-    _SMP_lock_Acquire( lock ); \
-  } while (0)
+static inline void _SMP_lock_ISR_disable_and_acquire(
+  SMP_lock_Control *lock,
+  SMP_lock_Context *context
+)
+{
+  _ISR_Disable_without_giant( context->isr_level );
+  _SMP_lock_Acquire( lock, context );
+}
 
 /**
  * @brief Releases the SMP lock and enables interrupts.
  *
  * @param[in,out] lock The SMP lock control.
- * @param[in] isr_cookie The ISR cookie.
+ * @param[in,out] context The local SMP lock context for an acquire and release
+ * pair.
  */
-#define _SMP_lock_Release_and_ISR_enable( lock, isr_cookie ) \
-  do { \
-    _SMP_lock_Release( lock ); \
-    _ISR_Enable_without_giant( isr_cookie ); \
-  } while (0)
+static inline void _SMP_lock_Release_and_ISR_enable(
+  SMP_lock_Control *lock,
+  SMP_lock_Context *context
+)
+{
+  _SMP_lock_Release( lock, context );
+  _ISR_Enable_without_giant( context->isr_level );
+}
 
 /**@}*/
 
diff --git a/cpukit/score/include/rtems/score/threaddispatch.h b/cpukit/score/include/rtems/score/threaddispatch.h
index 54786eb..5b25212 100644
--- a/cpukit/score/include/rtems/score/threaddispatch.h
+++ b/cpukit/score/include/rtems/score/threaddispatch.h
@@ -113,12 +113,11 @@ RTEMS_INLINE_ROUTINE void _Thread_Dispatch_initialization( void )
    *
    * The thread dispatch disable level is not altered by this function.
    *
-   * The only use case for this operation is in
-   * _SMP_Request_shutdown().
+   * The only use case for this operation is in _SMP_Request_shutdown().
    *
-   * @param[in] self_cpu The current processor index.
+   * @param[in] self_cpu The current processor.
    */
-  void _Giant_Drop( uint32_t self_cpu );
+  void _Giant_Drop( Per_CPU_Control *self_cpu );
 
   /**
    *  @brief Increments the thread dispatch level.
diff --git a/cpukit/score/include/rtems/score/todimpl.h b/cpukit/score/include/rtems/score/todimpl.h
index 097965c..a710b0f 100644
--- a/cpukit/score/include/rtems/score/todimpl.h
+++ b/cpukit/score/include/rtems/score/todimpl.h
@@ -176,11 +176,11 @@ typedef struct {
 
 SCORE_EXTERN TOD_Control _TOD;
 
-#define _TOD_Acquire( _tod, _isr_cookie ) \
-  _ISR_lock_ISR_disable_and_acquire( &( _tod )->lock, _isr_cookie )
+#define _TOD_Acquire( _tod, lock_context ) \
+  _ISR_lock_ISR_disable_and_acquire( &( _tod )->lock, lock_context )
 
-#define _TOD_Release( _tod, _isr_cookie ) \
-  _ISR_lock_Release_and_ISR_enable( &( _tod )->lock, _isr_cookie )
+#define _TOD_Release( _tod, lock_context ) \
+  _ISR_lock_Release_and_ISR_enable( &( _tod )->lock, lock_context )
 
 /**
  *  @brief Initializes the time of day handler.
diff --git a/cpukit/score/src/coretodget.c b/cpukit/score/src/coretodget.c
index 50ca8a0..6ddf86f 100644
--- a/cpukit/score/src/coretodget.c
+++ b/cpukit/score/src/coretodget.c
@@ -27,15 +27,15 @@ Timestamp_Control *_TOD_Get_with_nanoseconds(
 )
 {
   TOD_Control      *tod = &_TOD;
-  ISR_Level         level;
+  ISR_lock_Context  lock_context;
   Timestamp_Control offset;
   Timestamp_Control now;
   uint32_t          nanoseconds;
 
-  _TOD_Acquire( tod, level );
+  _TOD_Acquire( tod, &lock_context );
     nanoseconds = ( *tod->nanoseconds_since_last_tick )();
     now = *clock;
-  _TOD_Release( tod, level );
+  _TOD_Release( tod, &lock_context );
 
   _Timestamp_Set( &offset, 0, nanoseconds );
   _Timestamp_Add_to( &now, &offset );
diff --git a/cpukit/score/src/coretodsecondssinceepoch.c b/cpukit/score/src/coretodsecondssinceepoch.c
index 91445c0..620ad3d 100644
--- a/cpukit/score/src/coretodsecondssinceepoch.c
+++ b/cpukit/score/src/coretodsecondssinceepoch.c
@@ -21,12 +21,12 @@
 uint32_t _TOD_Seconds_since_epoch( void )
 {
   TOD_Control      *tod = &_TOD;
-  ISR_Level         level;
+  ISR_lock_Context  lock_context;
   Timestamp_Control now;
 
-  _TOD_Acquire( tod, level );
+  _TOD_Acquire( tod, &lock_context );
    now = tod->now;
-  _TOD_Release( tod, level );
+  _TOD_Release( tod, &lock_context );
 
   return _Timestamp_Get_seconds( &now );
 }
diff --git a/cpukit/score/src/coretodset.c b/cpukit/score/src/coretodset.c
index c265606..4262cf3 100644
--- a/cpukit/score/src/coretodset.c
+++ b/cpukit/score/src/coretodset.c
@@ -30,7 +30,7 @@ void _TOD_Set_with_timestamp(
   uint32_t nanoseconds = _Timestamp_Get_nanoseconds( tod_as_timestamp );
   Watchdog_Interval seconds_next = _Timestamp_Get_seconds( tod_as_timestamp );
   Watchdog_Interval seconds_now;
-  ISR_Level level;
+  ISR_lock_Context lock_context;
 
   _Thread_Disable_dispatch();
 
@@ -41,9 +41,9 @@ void _TOD_Set_with_timestamp(
   else
     _Watchdog_Adjust_seconds( WATCHDOG_FORWARD, seconds_next - seconds_now );
 
-  _TOD_Acquire( tod, level );
+  _TOD_Acquire( tod, &lock_context );
   tod->now = *tod_as_timestamp;
-  _TOD_Release( tod, level );
+  _TOD_Release( tod, &lock_context );
 
   tod->seconds_trigger = nanoseconds;
   tod->is_set = true;
diff --git a/cpukit/score/src/coretodtickle.c b/cpukit/score/src/coretodtickle.c
index c9f9597..055b40c 100644
--- a/cpukit/score/src/coretodtickle.c
+++ b/cpukit/score/src/coretodtickle.c
@@ -25,7 +25,7 @@
 void _TOD_Tickle_ticks( void )
 {
   TOD_Control       *tod = &_TOD;
-  ISR_Level          level;
+  ISR_lock_Context   lock_context;
   Timestamp_Control  tick;
   uint32_t           nanoseconds_per_tick;
 
@@ -37,7 +37,7 @@ void _TOD_Tickle_ticks( void )
   /* Update the counter of ticks since boot */
   _Watchdog_Ticks_since_boot += 1;
 
-  _TOD_Acquire( tod, level );
+  _TOD_Acquire( tod, &lock_context );
 
   /* Update the uptime */
   _Timestamp_Add_to( &tod->uptime, &tick );
@@ -45,7 +45,7 @@ void _TOD_Tickle_ticks( void )
   /* Update the current TOD */
   _Timestamp_Add_to( &tod->now, &tick );
 
-  _TOD_Release( tod, level );
+  _TOD_Release( tod, &lock_context );
 
   _TOD.seconds_trigger += nanoseconds_per_tick;
   if ( _TOD.seconds_trigger >= 1000000000UL ) {
diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c
index 3a7a845..50e5239 100644
--- a/cpukit/score/src/percpu.c
+++ b/cpukit/score/src/percpu.c
@@ -28,20 +28,6 @@
 
 static SMP_lock_Control _Per_CPU_State_lock = SMP_LOCK_INITIALIZER;
 
-static ISR_Level _Per_CPU_State_acquire( void )
-{
-  ISR_Level level;
-
-  _SMP_lock_ISR_disable_and_acquire( &_Per_CPU_State_lock, level );
-
-  return level;
-}
-
-static void _Per_CPU_State_release( ISR_Level level )
-{
-  _SMP_lock_Release_and_ISR_enable( &_Per_CPU_State_lock, level );
-}
-
 static void _Per_CPU_State_busy_wait(
   const Per_CPU_Control *per_cpu,
   Per_CPU_State new_state
@@ -126,12 +112,14 @@ void _Per_CPU_State_change(
   Per_CPU_State new_state
 )
 {
-  ISR_Level level;
+  SMP_lock_Control *lock = &_Per_CPU_State_lock;
+  SMP_lock_Context lock_context;
   Per_CPU_State next_state;
 
   _Per_CPU_State_busy_wait( per_cpu, new_state );
 
-  level = _Per_CPU_State_acquire();
+  _SMP_lock_ISR_disable_and_acquire( lock, &lock_context );
+
   next_state = _Per_CPU_State_get_next( per_cpu->state, new_state );
   per_cpu->state = next_state;
 
@@ -159,7 +147,7 @@ void _Per_CPU_State_change(
 
   _CPU_SMP_Processor_event_broadcast();
 
-  _Per_CPU_State_release( level );
+  _SMP_lock_Release_and_ISR_enable( lock, &lock_context );
 
   if (
     next_state == PER_CPU_STATE_SHUTDOWN
diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c
index e56073d..40d2ac3 100644
--- a/cpukit/score/src/smp.c
+++ b/cpukit/score/src/smp.c
@@ -32,7 +32,7 @@ void _SMP_Handler_initialize( void )
   for ( cpu = 0 ; cpu < max_cpus; ++cpu ) {
     Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
 
-    _ISR_lock_Initialize( &per_cpu->lock );
+    _SMP_ticket_lock_Initialize( &per_cpu->Lock );
   }
 
   /*
@@ -69,8 +69,7 @@ void _SMP_Start_multitasking_on_secondary_processor( void )
 
 void _SMP_Request_shutdown( void )
 {
-  uint32_t self = _SMP_Get_current_processor();
-  Per_CPU_Control *self_cpu = _Per_CPU_Get_by_index( self );
+  Per_CPU_Control *self_cpu = _Per_CPU_Get();
 
   _Per_CPU_State_change( self_cpu, PER_CPU_STATE_SHUTDOWN );
 
@@ -80,7 +79,7 @@ void _SMP_Request_shutdown( void )
    * In case the executing thread still holds SMP locks, then other processors
    * already waiting for this SMP lock will spin forever.
    */
-  _Giant_Drop( self );
+  _Giant_Drop( self_cpu );
 }
 
 void _SMP_Send_message( uint32_t cpu, uint32_t message )
diff --git a/cpukit/score/src/threaddispatchdisablelevel.c b/cpukit/score/src/threaddispatchdisablelevel.c
index b6eb49f..dc03a70 100644
--- a/cpukit/score/src/threaddispatchdisablelevel.c
+++ b/cpukit/score/src/threaddispatchdisablelevel.c
@@ -33,12 +33,13 @@ static Giant_Control _Giant = {
   .nest_level = 0
 };
 
-static void _Giant_Do_acquire( uint32_t self_cpu_index )
+static void _Giant_Do_acquire( Per_CPU_Control *self_cpu )
 {
   Giant_Control *giant = &_Giant;
+  uint32_t self_cpu_index = _Per_CPU_Get_index( self_cpu );
 
   if ( giant->owner_cpu != self_cpu_index ) {
-    _SMP_lock_Acquire( &giant->lock );
+    _SMP_lock_Acquire( &giant->lock, &self_cpu->Giant_lock_context );
     giant->owner_cpu = self_cpu_index;
     giant->nest_level = 1;
   } else {
@@ -46,48 +47,47 @@ static void _Giant_Do_acquire( uint32_t self_cpu_index )
   }
 }
 
-static void _Giant_Do_release( void )
+static void _Giant_Do_release( Per_CPU_Control *self_cpu )
 {
   Giant_Control *giant = &_Giant;
 
   --giant->nest_level;
   if ( giant->nest_level == 0 ) {
     giant->owner_cpu = NO_OWNER_CPU;
-    _SMP_lock_Release( &giant->lock );
+    _SMP_lock_Release( &giant->lock, &self_cpu->Giant_lock_context );
   }
 }
 
-void _Giant_Drop( uint32_t self_cpu )
+void _Giant_Drop( Per_CPU_Control *self_cpu )
 {
   Giant_Control *giant = &_Giant;
+  uint32_t self_cpu_index = _Per_CPU_Get_index( self_cpu );
 
   _Assert( _ISR_Get_level() != 0 );
 
-  if ( giant->owner_cpu == self_cpu ) {
+  if ( giant->owner_cpu == self_cpu_index ) {
     giant->nest_level = 0;
     giant->owner_cpu = NO_OWNER_CPU;
-    _SMP_lock_Release( &giant->lock );
+    _SMP_lock_Release( &giant->lock, &self_cpu->Giant_lock_context );
   }
 }
 
 uint32_t _Thread_Dispatch_increment_disable_level( void )
 {
   ISR_Level isr_level;
-  uint32_t self_cpu_index;
   uint32_t disable_level;
   Per_CPU_Control *self_cpu;
 
   _ISR_Disable_without_giant( isr_level );
 
   /*
-   * We must obtain the processor ID after interrupts are disabled to prevent
+   * We must obtain the processor after interrupts are disabled to prevent
    * thread migration.
    */
-  self_cpu_index = _SMP_Get_current_processor();
+  self_cpu = _Per_CPU_Get();
 
-  _Giant_Do_acquire( self_cpu_index );
+  _Giant_Do_acquire( self_cpu );
 
-  self_cpu = _Per_CPU_Get_by_index( self_cpu_index );
   disable_level = self_cpu->thread_dispatch_disable_level;
   ++disable_level;
   self_cpu->thread_dispatch_disable_level = disable_level;
@@ -110,7 +110,7 @@ uint32_t _Thread_Dispatch_decrement_disable_level( void )
   --disable_level;
   self_cpu->thread_dispatch_disable_level = disable_level;
 
-  _Giant_Do_release();
+  _Giant_Do_release( self_cpu );
   _Assert( disable_level != 0 || _Giant.owner_cpu == NO_OWNER_CPU );
 
   _ISR_Enable_without_giant( isr_level );
@@ -124,7 +124,7 @@ void _Giant_Acquire( void )
 
   _ISR_Disable_without_giant( isr_level );
   _Assert( _Thread_Dispatch_disable_level != 0 );
-  _Giant_Do_acquire( _SMP_Get_current_processor() );
+  _Giant_Do_acquire( _Per_CPU_Get() );
   _ISR_Enable_without_giant( isr_level );
 }
 
@@ -134,7 +134,7 @@ void _Giant_Release( void )
 
   _ISR_Disable_without_giant( isr_level );
   _Assert( _Thread_Dispatch_disable_level != 0 );
-  _Giant_Do_release();
+  _Giant_Do_release( _Per_CPU_Get() );
   _ISR_Enable_without_giant( isr_level );
 }
 
diff --git a/cpukit/score/src/threadhandler.c b/cpukit/score/src/threadhandler.c
index 4ecc789..161bb43 100644
--- a/cpukit/score/src/threadhandler.c
+++ b/cpukit/score/src/threadhandler.c
@@ -58,8 +58,10 @@
     #if defined(RTEMS_SMP)
       static SMP_lock_Control constructor_lock = SMP_LOCK_INITIALIZER;
 
+      SMP_lock_Context lock_context;
+
       if ( !doneConstructors ) {
-        _SMP_lock_Acquire( &constructor_lock );
+        _SMP_lock_Acquire( &constructor_lock, &lock_context );
     #endif
 
     #if defined(RTEMS_MULTIPROCESSING)
@@ -74,7 +76,7 @@
     #endif
 
     #if defined(RTEMS_SMP)
-        _SMP_lock_Release( &constructor_lock );
+        _SMP_lock_Release( &constructor_lock, &lock_context );
       }
     #endif
 
diff --git a/testsuites/smptests/smplock01/init.c b/testsuites/smptests/smplock01/init.c
index d454487..d67d7bc 100644
--- a/testsuites/smptests/smplock01/init.c
+++ b/testsuites/smptests/smplock01/init.c
@@ -97,10 +97,11 @@ static void test_0_body(
 )
 {
   unsigned long counter = 0;
+  SMP_lock_Context lock_context;
 
   while (assert_state(ctx, START_TEST)) {
-    _SMP_lock_Acquire(&ctx->lock);
-    _SMP_lock_Release(&ctx->lock);
+    _SMP_lock_Acquire(&ctx->lock, &lock_context);
+    _SMP_lock_Release(&ctx->lock, &lock_context);
     ++counter;
   }
 
@@ -116,11 +117,12 @@ static void test_1_body(
 )
 {
   unsigned long counter = 0;
+  SMP_lock_Context lock_context;
 
   while (assert_state(ctx, START_TEST)) {
-    _SMP_lock_Acquire(&ctx->lock);
+    _SMP_lock_Acquire(&ctx->lock, &lock_context);
     ++ctx->counter[test];
-    _SMP_lock_Release(&ctx->lock);
+    _SMP_lock_Release(&ctx->lock, &lock_context);
     ++counter;
   }
 
@@ -137,10 +139,11 @@ static void test_2_body(
 {
   unsigned long counter = 0;
   SMP_lock_Control lock = SMP_LOCK_INITIALIZER;
+  SMP_lock_Context lock_context;
 
   while (assert_state(ctx, START_TEST)) {
-    _SMP_lock_Acquire(&lock);
-    _SMP_lock_Release(&lock);
+    _SMP_lock_Acquire(&lock, &lock_context);
+    _SMP_lock_Release(&lock, &lock_context);
     ++counter;
   }
 
@@ -157,14 +160,15 @@ static void test_3_body(
 {
   unsigned long counter = 0;
   SMP_lock_Control lock = SMP_LOCK_INITIALIZER;
+  SMP_lock_Context lock_context;
 
   while (assert_state(ctx, START_TEST)) {
-    _SMP_lock_Acquire(&lock);
+    _SMP_lock_Acquire(&lock, &lock_context);
 
     /* The counter value is not interesting, only the access to it */
     ++ctx->counter[test];
 
-    _SMP_lock_Release(&lock);
+    _SMP_lock_Release(&lock, &lock_context);
     ++counter;
   }
 
@@ -189,11 +193,12 @@ static void test_4_body(
 )
 {
   unsigned long counter = 0;
+  SMP_lock_Context lock_context;
 
   while (assert_state(ctx, START_TEST)) {
-    _SMP_lock_Acquire(&ctx->lock);
+    _SMP_lock_Acquire(&ctx->lock, &lock_context);
     busy_section();
-    _SMP_lock_Release(&ctx->lock);
+    _SMP_lock_Release(&ctx->lock, &lock_context);
     ++counter;
   }
 
diff --git a/testsuites/sptests/sp37/init.c b/testsuites/sptests/sp37/init.c
index b6ab157..cd49ae2 100644
--- a/testsuites/sptests/sp37/init.c
+++ b/testsuites/sptests/sp37/init.c
@@ -162,20 +162,20 @@ static void test_isr_locks( void )
   ISR_Level normal_interrupt_level = _ISR_Get_level();
   ISR_lock_Control initialized = ISR_LOCK_INITIALIZER;
   ISR_lock_Control lock;
-  ISR_Level level;
+  ISR_lock_Context lock_context;
 
   _ISR_lock_Initialize( &lock );
   rtems_test_assert( memcmp( &lock, &initialized, sizeof( lock ) ) == 0 );
 
-  _ISR_lock_ISR_disable_and_acquire( &lock, level );
+  _ISR_lock_ISR_disable_and_acquire( &lock, &lock_context );
   rtems_test_assert( normal_interrupt_level != _ISR_Get_level() );
-  _ISR_lock_Release_and_ISR_enable( &lock, level );
+  _ISR_lock_Release_and_ISR_enable( &lock, &lock_context );
 
   rtems_test_assert( normal_interrupt_level == _ISR_Get_level() );
 
-  _ISR_lock_Acquire( &lock );
+  _ISR_lock_Acquire( &lock, &lock_context );
   rtems_test_assert( normal_interrupt_level == _ISR_Get_level() );
-  _ISR_lock_Release( &lock );
+  _ISR_lock_Release( &lock, &lock_context );
 
   rtems_test_assert( normal_interrupt_level == _ISR_Get_level() );
 }
@@ -196,20 +196,20 @@ static void test_interrupt_locks( void )
   rtems_mode normal_interrupt_level = get_interrupt_level();
   rtems_interrupt_lock initialized = RTEMS_INTERRUPT_LOCK_INITIALIZER;
   rtems_interrupt_lock lock;
-  rtems_interrupt_level level;
+  rtems_interrupt_lock_context lock_context;
 
   rtems_interrupt_lock_initialize( &lock );
   rtems_test_assert( memcmp( &lock, &initialized, sizeof( lock ) ) == 0 );
 
-  rtems_interrupt_lock_acquire( &lock, level );
+  rtems_interrupt_lock_acquire( &lock, &lock_context );
   rtems_test_assert( normal_interrupt_level != get_interrupt_level() );
-  rtems_interrupt_lock_release( &lock, level );
+  rtems_interrupt_lock_release( &lock, &lock_context );
 
   rtems_test_assert( normal_interrupt_level == get_interrupt_level() );
 
-  rtems_interrupt_lock_acquire_isr( &lock );
+  rtems_interrupt_lock_acquire_isr( &lock, &lock_context );
   rtems_test_assert( normal_interrupt_level == get_interrupt_level() );
-  rtems_interrupt_lock_release_isr( &lock );
+  rtems_interrupt_lock_release_isr( &lock, &lock_context );
 
   rtems_test_assert( normal_interrupt_level == get_interrupt_level() );
 }
diff --git a/testsuites/sptests/spcache01/init.c b/testsuites/sptests/spcache01/init.c
index 858aedc..faccbd4 100644
--- a/testsuites/sptests/spcache01/init.c
+++ b/testsuites/sptests/spcache01/init.c
@@ -38,8 +38,8 @@ CPU_STRUCTURE_ALIGNMENT static int data[1024];
 static void test_data_flush_and_invalidate(void)
 {
   if (rtems_cache_get_data_line_size() > 0) {
-    rtems_interrupt_level level;
-    rtems_interrupt_lock lock = RTEMS_INTERRUPT_LOCK_INITIALIZER;
+    rtems_interrupt_lock lock;
+    rtems_interrupt_lock_context lock_context;
     volatile int *vdata = &data[0];
     int n = 32;
     int i;
@@ -48,7 +48,8 @@ static void test_data_flush_and_invalidate(void)
 
     printf("data cache flush and invalidate test\n");
 
-    rtems_interrupt_lock_acquire(&lock, level);
+    rtems_interrupt_lock_initialize(&lock);
+    rtems_interrupt_lock_acquire(&lock, &lock_context);
 
     for (i = 0; i < n; ++i) {
       vdata[i] = i;
@@ -88,7 +89,7 @@ static void test_data_flush_and_invalidate(void)
       rtems_test_assert(vdata[i] == ~i);
     }
 
-    rtems_interrupt_lock_release(&lock, level);
+    rtems_interrupt_lock_release(&lock, &lock_context);
 
     printf(
       "data cache operations by line passed the test (%s cache detected)\n",
@@ -159,13 +160,15 @@ static uint64_t store(void)
 
 static void test_timing(void)
 {
-  rtems_interrupt_level level;
-  rtems_interrupt_lock lock = RTEMS_INTERRUPT_LOCK_INITIALIZER;
+  rtems_interrupt_lock lock;
+  rtems_interrupt_lock_context lock_context;
   size_t data_size = sizeof(data);
   uint64_t d[3];
   uint32_t cache_level;
   size_t cache_size;
 
+  rtems_interrupt_lock_initialize(&lock);
+
   printf(
     "data cache line size %zi bytes\n"
     "data cache size %zi bytes\n",
@@ -185,14 +188,14 @@ static void test_timing(void)
     cache_size = rtems_cache_get_data_cache_size(cache_level);
   }
 
-  rtems_interrupt_lock_acquire(&lock, level);
+  rtems_interrupt_lock_acquire(&lock, &lock_context);
 
   d[0] = load();
   d[1] = load();
   rtems_cache_flush_entire_data();
   d[2] = load();
 
-  rtems_interrupt_lock_release(&lock, level);
+  rtems_interrupt_lock_release(&lock, &lock_context);
 
   printf(
     "load %zi bytes with flush entire data\n"
@@ -205,14 +208,14 @@ static void test_timing(void)
     d[2]
   );
 
-  rtems_interrupt_lock_acquire(&lock, level);
+  rtems_interrupt_lock_acquire(&lock, &lock_context);
 
   d[0] = load();
   d[1] = load();
   rtems_cache_flush_multiple_data_lines(&data[0], sizeof(data));
   d[2] = load();
 
-  rtems_interrupt_lock_release(&lock, level);
+  rtems_interrupt_lock_release(&lock, &lock_context);
 
   printf(
     "load %zi bytes with flush multiple data\n"
@@ -225,14 +228,14 @@ static void test_timing(void)
     d[2]
   );
 
-  rtems_interrupt_lock_acquire(&lock, level);
+  rtems_interrupt_lock_acquire(&lock, &lock_context);
 
   d[0] = load();
   d[1] = load();
   rtems_cache_invalidate_multiple_data_lines(&data[0], sizeof(data));
   d[2] = load();
 
-  rtems_interrupt_lock_release(&lock, level);
+  rtems_interrupt_lock_release(&lock, &lock_context);
 
   printf(
     "load %zi bytes with invalidate multiple data\n"
@@ -245,14 +248,14 @@ static void test_timing(void)
     d[2]
   );
 
-  rtems_interrupt_lock_acquire(&lock, level);
+  rtems_interrupt_lock_acquire(&lock, &lock_context);
 
   d[0] = store();
   d[1] = store();
   rtems_cache_flush_entire_data();
   d[2] = store();
 
-  rtems_interrupt_lock_release(&lock, level);
+  rtems_interrupt_lock_release(&lock, &lock_context);
 
   printf(
     "store %zi bytes with flush entire data\n"
@@ -265,14 +268,14 @@ static void test_timing(void)
     d[2]
   );
 
-  rtems_interrupt_lock_acquire(&lock, level);
+  rtems_interrupt_lock_acquire(&lock, &lock_context);
 
   d[0] = store();
   d[1] = store();
   rtems_cache_flush_multiple_data_lines(&data[0], sizeof(data));
   d[2] = store();
 
-  rtems_interrupt_lock_release(&lock, level);
+  rtems_interrupt_lock_release(&lock, &lock_context);
 
   printf(
     "store %zi bytes with flush multiple data\n"
@@ -285,14 +288,14 @@ static void test_timing(void)
     d[2]
   );
 
-  rtems_interrupt_lock_acquire(&lock, level);
+  rtems_interrupt_lock_acquire(&lock, &lock_context);
 
   d[0] = store();
   d[1] = store();
   rtems_cache_invalidate_multiple_data_lines(&data[0], sizeof(data));
   d[2] = store();
 
-  rtems_interrupt_lock_release(&lock, level);
+  rtems_interrupt_lock_release(&lock, &lock_context);
 
   printf(
     "store %zi bytes with invalidate multiple data\n"
@@ -324,14 +327,14 @@ static void test_timing(void)
     cache_size = rtems_cache_get_instruction_cache_size(cache_level);
   }
 
-  rtems_interrupt_lock_acquire(&lock, level);
+  rtems_interrupt_lock_acquire(&lock, &lock_context);
 
   d[0] = do_some_work();
   d[1] = do_some_work();
   rtems_cache_invalidate_entire_instruction();
   d[2] = do_some_work();
 
-  rtems_interrupt_lock_release(&lock, level);
+  rtems_interrupt_lock_release(&lock, &lock_context);
 
   printf(
     "invalidate entire instruction\n"
@@ -343,14 +346,14 @@ static void test_timing(void)
     d[2]
   );
 
-  rtems_interrupt_lock_acquire(&lock, level);
+  rtems_interrupt_lock_acquire(&lock, &lock_context);
 
   d[0] = do_some_work();
   d[1] = do_some_work();
   rtems_cache_invalidate_multiple_instruction_lines(do_some_work, 4096);
   d[2] = do_some_work();
 
-  rtems_interrupt_lock_release(&lock, level);
+  rtems_interrupt_lock_release(&lock, &lock_context);
 
   printf(
     "invalidate multiple instruction\n"
diff --git a/testsuites/sptests/spnsext01/init.c b/testsuites/sptests/spnsext01/init.c
index cbe3c13..788ba0b 100644
--- a/testsuites/sptests/spnsext01/init.c
+++ b/testsuites/sptests/spnsext01/init.c
@@ -21,8 +21,8 @@
 static rtems_task Init(rtems_task_argument argument)
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
-  rtems_interrupt_lock lock = RTEMS_INTERRUPT_LOCK_INITIALIZER;
-  rtems_interrupt_level level;
+  rtems_interrupt_lock lock;
+  rtems_interrupt_lock_context lock_context;
   rtems_interval t0 = 0;
   rtems_interval t1 = 0;
   int i = 0;
@@ -51,7 +51,8 @@ static rtems_task Init(rtems_task_argument argument)
 
   n = (3 * n) / 2;
 
-  rtems_interrupt_lock_acquire(&lock, level);
+  rtems_interrupt_lock_initialize(&lock);
+  rtems_interrupt_lock_acquire(&lock, &lock_context);
   sc = rtems_clock_get_uptime(&uptime);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
   for (i = 0; i < n; ++i) {
@@ -63,7 +64,7 @@ static rtems_task Init(rtems_task_argument argument)
     rtems_test_assert(!_Timespec_Less_than(&new_uptime, &uptime));
     uptime = new_uptime;
   }
-  rtems_interrupt_lock_release(&lock, level);
+  rtems_interrupt_lock_release(&lock, &lock_context);
 
   puts("*** END OF TEST NANO SECONDS EXTENSION 1 ***");
 
diff --git a/testsuites/tmtests/tmcontext01/init.c b/testsuites/tmtests/tmcontext01/init.c
index ba3bcec..130952b 100644
--- a/testsuites/tmtests/tmcontext01/init.c
+++ b/testsuites/tmtests/tmcontext01/init.c
@@ -129,8 +129,8 @@ static void sort_t(void)
 
 static void test_by_function_level(int fl, bool dirty)
 {
-  rtems_interrupt_level level;
   rtems_interrupt_lock lock = RTEMS_INTERRUPT_LOCK_INITIALIZER;
+  rtems_interrupt_lock_context lock_context;
   int s;
   uint64_t min;
   uint64_t q1;
@@ -138,13 +138,13 @@ static void test_by_function_level(int fl, bool dirty)
   uint64_t q3;
   uint64_t max;
 
-  rtems_interrupt_lock_acquire(&lock, level);
+  rtems_interrupt_lock_acquire(&lock, &lock_context);
 
   for (s = 0; s < SAMPLES; ++s) {
     call_at_level(fl, fl, s, dirty);
   }
 
-  rtems_interrupt_lock_release(&lock, level);
+  rtems_interrupt_lock_release(&lock, &lock_context);
 
   sort_t();
 




More information about the vc mailing list