[rtems commit] score: Rework MP thread queue callout support

Sebastian Huber sebh at rtems.org
Wed Apr 6 08:32:11 UTC 2016


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Apr  1 11:38:47 2016 +0200

score: Rework MP thread queue callout support

The thread queue implementation was heavily reworked to support SMP.
This broke the multiprocessing support of the thread queues.  This is
fixed by this patch.

A thread proxy is unblocked due to three reasons
  1) timeout,
  2) request satisfaction, and
  3) extraction.

In case 1) no MPCI message must be sent.  This is ensured via the
_Thread_queue_MP_callout_do_nothing() callout set during
_Thread_MP_Allocate_proxy().

In case 2) and 3) an MPCI message must be sent.  In case we interrupt
the blocking operation during _Thread_queue_Enqueue_critical(), then
this message must be sent by the blocking thread.  For this the new
fields Thread_Proxy_control::thread_queue_callout and
Thread_Proxy_control::thread_queue_id are used.

Delete the individual API MP callout types and use
Thread_queue_MP_callout throughout.  This type is only defined in
multiprocessing configurations.  Prefix the multiprocessing parameters
with mp_ to ease code review.  Multiprocessing specific parameters are
optional due to use of a similar macro pattern.  There is no overhead
for non-multiprocessing configurations.

---

 cpukit/libnetworking/rtems/rtems_glue.c            |   2 +-
 cpukit/posix/include/rtems/posix/pthreadimpl.h     |   4 +-
 cpukit/posix/src/condsignalsupp.c                  |   4 +-
 cpukit/posix/src/mqueuesendsupp.c                  |   2 +-
 cpukit/posix/src/mutexsetprioceiling.c             |   2 +-
 cpukit/posix/src/mutexunlock.c                     |   2 +-
 cpukit/posix/src/pbarrierwait.c                    |   4 +-
 cpukit/posix/src/sempost.c                         |   6 +-
 cpukit/rtems/src/barrierrelease.c                  |   2 +-
 cpukit/rtems/src/barrierwait.c                     |   4 +-
 cpukit/rtems/src/msgqbroadcast.c                   |   6 +-
 cpukit/rtems/src/msgqsend.c                        |  25 +-
 cpukit/rtems/src/msgqurgent.c                      |   8 +-
 cpukit/rtems/src/semrelease.c                      |  24 +-
 cpukit/score/include/rtems/score/corebarrierimpl.h | 103 +++++--
 cpukit/score/include/rtems/score/coremsgimpl.h     | 304 ++++++++++++++-------
 cpukit/score/include/rtems/score/coremuteximpl.h   |  64 ++---
 cpukit/score/include/rtems/score/coresemimpl.h     |  94 ++++---
 cpukit/score/include/rtems/score/thread.h          |  14 +-
 cpukit/score/include/rtems/score/threadq.h         |  16 ++
 cpukit/score/include/rtems/score/threadqimpl.h     | 213 ++++++++++++---
 cpukit/score/src/apimutexunlock.c                  |   2 +-
 cpukit/score/src/condition.c                       |   4 +-
 cpukit/score/src/corebarrierrelease.c              |  37 +--
 cpukit/score/src/corebarrierwait.c                 |  19 +-
 cpukit/score/src/coremsgbroadcast.c                |  30 +-
 cpukit/score/src/coremsgseize.c                    |  24 +-
 cpukit/score/src/coremsgsubmit.c                   |  40 +--
 cpukit/score/src/coremutexsurrender.c              |  46 +---
 cpukit/score/src/corerwlockrelease.c               |   4 +-
 cpukit/score/src/futex.c                           |   4 +-
 cpukit/score/src/mutex.c                           |   6 +-
 cpukit/score/src/semaphore.c                       |   2 +
 cpukit/score/src/threadmp.c                        |   2 +
 cpukit/score/src/threadq.c                         |  10 +
 cpukit/score/src/threadqenqueue.c                  | 113 ++++++--
 cpukit/score/src/threadqflush.c                    |   7 +-
 37 files changed, 795 insertions(+), 458 deletions(-)

diff --git a/cpukit/libnetworking/rtems/rtems_glue.c b/cpukit/libnetworking/rtems/rtems_glue.c
index 5a43a72..17df156 100644
--- a/cpukit/libnetworking/rtems/rtems_glue.c
+++ b/cpukit/libnetworking/rtems/rtems_glue.c
@@ -427,8 +427,8 @@ rtems_bsdnet_semaphore_release (void)
         _ISR_lock_ISR_disable(&lock_context);
 	status = _CORE_mutex_Surrender (
 		&the_networkSemaphore->Core_control.mutex,
-		networkSemaphore,
 		NULL,
+		0,
                 &lock_context
 		);
 	if (status != CORE_MUTEX_STATUS_SUCCESSFUL)
diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h
index 14db6f0..42f10b0 100644
--- a/cpukit/posix/include/rtems/posix/pthreadimpl.h
+++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h
@@ -217,7 +217,9 @@ RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Join_dequeue(
 {
   return _Thread_queue_Dequeue(
     &api->Join_List,
-    POSIX_THREAD_JOIN_TQ_OPERATIONS
+    POSIX_THREAD_JOIN_TQ_OPERATIONS,
+    NULL,
+    0
   );
 }
 
diff --git a/cpukit/posix/src/condsignalsupp.c b/cpukit/posix/src/condsignalsupp.c
index b2a0b1a..9c67ddc 100644
--- a/cpukit/posix/src/condsignalsupp.c
+++ b/cpukit/posix/src/condsignalsupp.c
@@ -49,7 +49,9 @@ int _POSIX_Condition_variables_Signal_support(
       do {
         the_thread = _Thread_queue_Dequeue(
           &the_cond->Wait_queue,
-          POSIX_CONDITION_VARIABLES_TQ_OPERATIONS
+          POSIX_CONDITION_VARIABLES_TQ_OPERATIONS,
+          NULL,
+          0
         );
         if ( !the_thread )
           the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
diff --git a/cpukit/posix/src/mqueuesendsupp.c b/cpukit/posix/src/mqueuesendsupp.c
index 976d1e0..e158706 100644
--- a/cpukit/posix/src/mqueuesendsupp.c
+++ b/cpukit/posix/src/mqueuesendsupp.c
@@ -105,8 +105,8 @@ int _POSIX_Message_queue_Send_support(
         executing,
         msg_ptr,
         msg_len,
-        mqdes,      /* mqd_t is an object id */
         NULL,
+        0,
         _POSIX_Message_queue_Priority_to_core( msg_prio ),
         do_wait,
         timeout,   /* no timeout */
diff --git a/cpukit/posix/src/mutexsetprioceiling.c b/cpukit/posix/src/mutexsetprioceiling.c
index 8b966ba..718bfc4 100644
--- a/cpukit/posix/src/mutexsetprioceiling.c
+++ b/cpukit/posix/src/mutexsetprioceiling.c
@@ -81,8 +81,8 @@ int pthread_mutex_setprioceiling(
        */
       _CORE_mutex_Surrender(
         &the_mutex->Mutex,
-        the_mutex->Object.id,
         NULL,
+        0,
         &lock_context
       );
 
diff --git a/cpukit/posix/src/mutexunlock.c b/cpukit/posix/src/mutexunlock.c
index a8b28db..1a83a0a 100644
--- a/cpukit/posix/src/mutexunlock.c
+++ b/cpukit/posix/src/mutexunlock.c
@@ -52,8 +52,8 @@ int pthread_mutex_unlock(
     case OBJECTS_LOCAL:
       status = _CORE_mutex_Surrender(
         &the_mutex->Mutex,
-        the_mutex->Object.id,
         NULL,
+        0,
         &lock_context
       );
       return _POSIX_Mutex_Translate_core_mutex_return_code( status );
diff --git a/cpukit/posix/src/pbarrierwait.c b/cpukit/posix/src/pbarrierwait.c
index 560e101..fd94e45 100644
--- a/cpukit/posix/src/pbarrierwait.c
+++ b/cpukit/posix/src/pbarrierwait.c
@@ -55,10 +55,10 @@ int pthread_barrier_wait(
       _CORE_barrier_Wait(
         &the_barrier->Barrier,
         executing,
-        the_barrier->Object.id,
         true,
         0,
-        NULL
+        NULL,
+        0
       );
       _Objects_Put( &the_barrier->Object );
       return _POSIX_Barrier_Translate_core_barrier_return_code(
diff --git a/cpukit/posix/src/sempost.c b/cpukit/posix/src/sempost.c
index aa0c974..8e8cce9 100644
--- a/cpukit/posix/src/sempost.c
+++ b/cpukit/posix/src/sempost.c
@@ -48,12 +48,8 @@ int sem_post(
     case OBJECTS_LOCAL:
       _CORE_semaphore_Surrender(
         &the_semaphore->Semaphore,
-        the_semaphore->Object.id,
-#if defined(RTEMS_MULTIPROCESSING)
-        NULL,        /* POSIX Semaphores are local only */
-#else
         NULL,
-#endif
+        0,
         &lock_context
       );
       return 0;
diff --git a/cpukit/rtems/src/barrierrelease.c b/cpukit/rtems/src/barrierrelease.c
index 1901df5..02500e5 100644
--- a/cpukit/rtems/src/barrierrelease.c
+++ b/cpukit/rtems/src/barrierrelease.c
@@ -54,7 +54,7 @@ rtems_status_code rtems_barrier_release(
   switch ( location ) {
 
     case OBJECTS_LOCAL:
-      *released = _CORE_barrier_Release( &the_barrier->Barrier, id, NULL );
+      *released = _CORE_barrier_Release( &the_barrier->Barrier, NULL, 0 );
       _Objects_Put( &the_barrier->Object );
       return RTEMS_SUCCESSFUL;
 
diff --git a/cpukit/rtems/src/barrierwait.c b/cpukit/rtems/src/barrierwait.c
index 3a30593..b2999eb 100644
--- a/cpukit/rtems/src/barrierwait.c
+++ b/cpukit/rtems/src/barrierwait.c
@@ -43,10 +43,10 @@ rtems_status_code rtems_barrier_wait(
       _CORE_barrier_Wait(
         &the_barrier->Barrier,
         executing,
-        id,
         true,
         timeout,
-        NULL
+        NULL,
+        0
       );
       _Objects_Put( &the_barrier->Object );
       return _Barrier_Translate_core_barrier_return_code(
diff --git a/cpukit/rtems/src/msgqbroadcast.c b/cpukit/rtems/src/msgqbroadcast.c
index aabbf3f..7bd7e3b 100644
--- a/cpukit/rtems/src/msgqbroadcast.c
+++ b/cpukit/rtems/src/msgqbroadcast.c
@@ -60,12 +60,8 @@ rtems_status_code rtems_message_queue_broadcast(
                       &the_message_queue->message_queue,
                       buffer,
                       size,
+                      _Message_queue_Core_message_queue_mp_support,
                       id,
-                      #if defined(RTEMS_MULTIPROCESSING)
-                        _Message_queue_Core_message_queue_mp_support,
-                      #else
-                        NULL,
-                      #endif
                       count,
                       &lock_context
                     );
diff --git a/cpukit/rtems/src/msgqsend.c b/cpukit/rtems/src/msgqsend.c
index fb3979e..6f3009d 100644
--- a/cpukit/rtems/src/msgqsend.c
+++ b/cpukit/rtems/src/msgqsend.c
@@ -30,29 +30,6 @@
 #include <rtems/rtems/options.h>
 #include <rtems/rtems/support.h>
 
-/*
- *
- *  rtems_message_queue_send
- *
- *  This routine implements the directive rtems_message_queue_send.  It sends a
- *  message to the specified message queue.
- *
- *  Input parameters:
- *    id     - pointer to message queue
- *    buffer - pointer to message buffer
- *    size   - size of message to send
- *
- *  Output parameters:
- *    RTEMS_SUCCESSFUL - if successful
- *    error code       - if unsuccessful
- */
-
-#if defined(RTEMS_MULTIPROCESSING)
-#define MESSAGE_QUEUE_MP_HANDLER _Message_queue_Core_message_queue_mp_support
-#else
-#define MESSAGE_QUEUE_MP_HANDLER NULL
-#endif
-
 rtems_status_code rtems_message_queue_send(
   rtems_id    id,
   const void *buffer,
@@ -79,8 +56,8 @@ rtems_status_code rtems_message_queue_send(
         &the_message_queue->message_queue,
         buffer,
         size,
+        _Message_queue_Core_message_queue_mp_support,
         id,
-        MESSAGE_QUEUE_MP_HANDLER,
         false,   /* sender does not block */
         0,       /* no timeout */
         &lock_context
diff --git a/cpukit/rtems/src/msgqurgent.c b/cpukit/rtems/src/msgqurgent.c
index e6ae5ef..a328741 100644
--- a/cpukit/rtems/src/msgqurgent.c
+++ b/cpukit/rtems/src/msgqurgent.c
@@ -30,12 +30,6 @@
 #include <rtems/rtems/options.h>
 #include <rtems/rtems/support.h>
 
-#if defined(RTEMS_MULTIPROCESSING)
-#define MESSAGE_QUEUE_MP_HANDLER _Message_queue_Core_message_queue_mp_support
-#else
-#define MESSAGE_QUEUE_MP_HANDLER NULL
-#endif
-
 rtems_status_code rtems_message_queue_urgent(
   rtems_id    id,
   const void *buffer,
@@ -62,8 +56,8 @@ rtems_status_code rtems_message_queue_urgent(
         &the_message_queue->message_queue,
         buffer,
         size,
+        _Message_queue_Core_message_queue_mp_support,
         id,
-        MESSAGE_QUEUE_MP_HANDLER,
         false,   /* sender does not block */
         0,       /* no timeout */
         &lock_context
diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c
index 5d41b6c..4a6ccb2 100644
--- a/cpukit/rtems/src/semrelease.c
+++ b/cpukit/rtems/src/semrelease.c
@@ -31,28 +31,8 @@
 #include <rtems/score/coremuteximpl.h>
 #include <rtems/score/coresemimpl.h>
 #include <rtems/score/thread.h>
-
 #include <rtems/score/interr.h>
 
-/*
- *  rtems_semaphore_release
- *
- *  This directive allows a thread to release a semaphore.
- *
- *  Input parameters:
- *    id - semaphore id
- *
- *  Output parameters:
- *    RTEMS_SUCCESSFUL - if successful
- *    error code        - if unsuccessful
- */
-
-#if defined(RTEMS_MULTIPROCESSING)
-#define MUTEX_MP_SUPPORT _Semaphore_Core_mutex_mp_support
-#else
-#define MUTEX_MP_SUPPORT NULL
-#endif
-
 rtems_status_code rtems_semaphore_release(
   rtems_id   id
 )
@@ -88,16 +68,16 @@ rtems_status_code rtems_semaphore_release(
       if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
         mutex_status = _CORE_mutex_Surrender(
           &the_semaphore->Core_control.mutex,
+          _Semaphore_Core_mutex_mp_support,
           id,
-          MUTEX_MP_SUPPORT,
           &lock_context
         );
         return _Semaphore_Translate_core_mutex_return_code( mutex_status );
       } else {
         semaphore_status = _CORE_semaphore_Surrender(
           &the_semaphore->Core_control.semaphore,
+          _Semaphore_Core_mutex_mp_support,
           id,
-          MUTEX_MP_SUPPORT,
           &lock_context
         );
         return
diff --git a/cpukit/score/include/rtems/score/corebarrierimpl.h b/cpukit/score/include/rtems/score/corebarrierimpl.h
index 7e1c0ab..8754cec 100644
--- a/cpukit/score/include/rtems/score/corebarrierimpl.h
+++ b/cpukit/score/include/rtems/score/corebarrierimpl.h
@@ -65,15 +65,6 @@ typedef enum {
 #define CORE_BARRIER_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
 
 /**
- *  The following type defines the callout which the API provides
- *  to support global/multiprocessor operations on barriers.
- */
-typedef void ( *CORE_barrier_API_mp_support_callout )(
-                 Thread_Control *,
-                 Objects_Id
-             );
-
-/**
  *  @brief Initialize core barrier.
  *
  *  This routine initializes the barrier based on the parameters passed.
@@ -93,6 +84,18 @@ RTEMS_INLINE_ROUTINE void _CORE_barrier_Destroy(
   _Thread_queue_Destroy( &the_barrier->Wait_queue );
 }
 
+void _CORE_barrier_Do_wait(
+  CORE_barrier_Control    *the_barrier,
+  Thread_Control          *executing,
+  bool                     wait,
+  Watchdog_Interval        timeout
+#if defined(RTEMS_MULTIPROCESSING)
+  ,
+  Thread_queue_MP_callout  mp_callout,
+  Objects_Id               mp_id
+#endif
+);
+
 /**
  *  @brief Wait for the barrier.
  *
@@ -103,22 +106,56 @@ RTEMS_INLINE_ROUTINE void _CORE_barrier_Destroy(
  *
  *  @param[in] the_barrier is the barrier to wait for
  *  @param[in,out] executing The currently executing thread.
- *  @param[in] id is the id of the object being waited upon
  *  @param[in] wait is true if the calling thread is willing to wait
  *  @param[in] timeout is the number of ticks the calling thread is willing
  *         to wait if @a wait is true.
- *  @param[in] api_barrier_mp_support is the routine to invoke if the
+ *  @param[in] mp_callout is the routine to invoke if the
  *         thread unblocked is remote
+ *  @param[in] mp_id is the id of the object being waited upon
  *
  * @note Status is returned via the thread control block.
  */
-void _CORE_barrier_Wait(
-  CORE_barrier_Control                *the_barrier,
-  Thread_Control                      *executing,
-  Objects_Id                           id,
-  bool                                 wait,
-  Watchdog_Interval                    timeout,
-  CORE_barrier_API_mp_support_callout  api_barrier_mp_support
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _CORE_barrier_Wait( \
+    the_barrier, \
+    executing, \
+    wait, \
+    timeout, \
+    mp_callout, \
+    mp_id \
+  ) \
+    _CORE_barrier_Do_wait( \
+      the_barrier, \
+      executing, \
+      wait, \
+      timeout, \
+      mp_callout, \
+      mp_id \
+    )
+#else
+  #define _CORE_barrier_Wait( \
+    the_barrier, \
+    executing, \
+    wait, \
+    timeout, \
+    mp_callout, \
+    mp_id \
+  ) \
+    _CORE_barrier_Do_wait( \
+      the_barrier, \
+      executing, \
+      wait, \
+      timeout \
+    )
+#endif
+
+uint32_t _CORE_barrier_Do_release(
+  CORE_barrier_Control    *the_barrier
+#if defined(RTEMS_MULTIPROCESSING)
+  ,
+  Thread_queue_MP_callout  mp_callout,
+  Objects_Id               mp_id
+#endif
 );
 
 /**
@@ -128,17 +165,33 @@ void _CORE_barrier_Wait(
  *  for the barrier will be readied.
  *
  *  @param[in] the_barrier is the barrier to surrender
- *  @param[in] id is the id of the object for a remote unblock
- *  @param[in] api_barrier_mp_support is the routine to invoke if the
+ *  @param[in] mp_callout is the routine to invoke if the
  *         thread unblocked is remote
+ *  @param[in] mp_id is the id of the object for a remote unblock
  *
  *  @retval the number of unblocked threads
  */
-uint32_t _CORE_barrier_Release(
-  CORE_barrier_Control                *the_barrier,
-  Objects_Id                           id,
-  CORE_barrier_API_mp_support_callout  api_barrier_mp_support
-);
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _CORE_barrier_Release( \
+    the_barrier, \
+    mp_callout, \
+    mp_id \
+  ) \
+    _CORE_barrier_Do_release( \
+      the_barrier, \
+      mp_callout, \
+      mp_id \
+    )
+#else
+  #define _CORE_barrier_Release( \
+    the_barrier, \
+    mp_callout, \
+    mp_id \
+  ) \
+    _CORE_barrier_Do_release( \
+      the_barrier \
+    )
+#endif
 
 /* Must be a macro due to the multiprocessing dependent parameters */
 #define _CORE_barrier_Flush( \
diff --git a/cpukit/score/include/rtems/score/coremsgimpl.h b/cpukit/score/include/rtems/score/coremsgimpl.h
index 5b7abb2..d7d5c46 100644
--- a/cpukit/score/include/rtems/score/coremsgimpl.h
+++ b/cpukit/score/include/rtems/score/coremsgimpl.h
@@ -101,17 +101,6 @@ typedef enum {
 #define CORE_MESSAGE_QUEUE_STATUS_LAST CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT
 
 /**
- *  @brief Callout provides to support global/multiprocessor operations.
- *
- *  The following type defines the callout which the API provides
- *  to support global/multiprocessor operations on message_queues.
- */
-typedef void ( *CORE_message_queue_API_mp_support_callout )(
-                 Thread_Control *,
-                 Objects_Id
-             );
-
-/**
  *  @brief Initialize a message queue.
  *
  *  This package is the implementation of the CORE Message Queue Handler.
@@ -229,6 +218,18 @@ uint32_t   _CORE_message_queue_Flush(
   );
 #endif
 
+CORE_message_queue_Status _CORE_message_queue_Do_broadcast(
+  CORE_message_queue_Control *the_message_queue,
+  const void                 *buffer,
+  size_t                      size,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout     mp_callout,
+  Objects_Id                  mp_id,
+#endif
+  uint32_t                   *count,
+  ISR_lock_Context           *lock_context
+);
+
 /**
  *  @brief Broadcast a message to the message queue.
  *
@@ -242,24 +243,67 @@ uint32_t   _CORE_message_queue_Flush(
  *  @param[in] the_message_queue points to the message queue
  *  @param[in] buffer is the starting address of the message to broadcast
  *  @param[in] size is the size of the message being broadcast
- *  @param[in] id is the RTEMS object Id associated with this message queue.
- *         It is used when unblocking a remote thread.
- *  @param[in] api_message_queue_mp_support is the routine to invoke if
+ *  @param[in] mp_callout is the routine to invoke if
  *         a thread that is unblocked is actually a remote thread.
+ *  @param[in] mp_id is the RTEMS object Id associated with this message queue.
+ *         It is used when unblocking a remote thread.
  *  @param[out] count points to the variable that will contain the
  *         number of tasks that are sent this message
  *  @param[in] lock_context The lock context of the interrupt disable.
  *  @retval @a *count will contain the number of messages sent
  *  @retval indication of the successful completion or reason for failure
  */
-CORE_message_queue_Status _CORE_message_queue_Broadcast(
-  CORE_message_queue_Control                *the_message_queue,
-  const void                                *buffer,
-  size_t                                     size,
-  Objects_Id                                 id,
-  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
-  uint32_t                                  *count,
-  ISR_lock_Context                          *lock_context
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _CORE_message_queue_Broadcast( \
+    the_message_queue, \
+    buffer, \
+    size, \
+    mp_callout, \
+    mp_id, \
+    count, \
+    lock_context \
+  ) \
+    _CORE_message_queue_Do_broadcast( \
+      the_message_queue, \
+      buffer, \
+      size, \
+      mp_callout, \
+      mp_id, \
+      count, \
+      lock_context \
+    )
+#else
+  #define _CORE_message_queue_Broadcast( \
+    the_message_queue, \
+    buffer, \
+    size, \
+    mp_callout, \
+    mp_id, \
+    count, \
+    lock_context \
+  ) \
+    _CORE_message_queue_Do_broadcast( \
+      the_message_queue, \
+      buffer, \
+      size, \
+      count, \
+      lock_context \
+    )
+#endif
+
+CORE_message_queue_Status _CORE_message_queue_Do_submit(
+  CORE_message_queue_Control       *the_message_queue,
+  Thread_Control                   *executing,
+  const void                       *buffer,
+  size_t                            size,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout           mp_callout,
+  Objects_Id                        mp_id,
+#endif
+  CORE_message_queue_Submit_types   submit_type,
+  bool                              wait,
+  Watchdog_Interval                 timeout,
+  ISR_lock_Context                 *lock_context
 );
 
 /**
@@ -275,10 +319,10 @@ CORE_message_queue_Status _CORE_message_queue_Broadcast(
  *  @param[in] the_message_queue points to the message queue
  *  @param[in] buffer is the starting address of the message to send
  *  @param[in] size is the size of the message being send
- *  @param[in] id is the RTEMS object Id associated with this message queue.
- *         It is used when unblocking a remote thread.
- *  @param[in] api_message_queue_mp_support is the routine to invoke if
+ *  @param[in] mp_callout is the routine to invoke if
  *         a thread that is unblocked is actually a remote thread.
+ *  @param[in] mp_id is the RTEMS object Id associated with this message queue.
+ *         It is used when unblocking a remote thread.
  *  @param[in] submit_type determines whether the message is prepended,
  *         appended, or enqueued in priority order.
  *  @param[in] wait indicates whether the calling thread is willing to block
@@ -288,18 +332,55 @@ CORE_message_queue_Status _CORE_message_queue_Broadcast(
  *  @param[in] lock_context The lock context of the interrupt disable.
  *  @retval indication of the successful completion or reason for failure
  */
-CORE_message_queue_Status _CORE_message_queue_Submit(
-  CORE_message_queue_Control                *the_message_queue,
-  Thread_Control                            *executing,
-  const void                                *buffer,
-  size_t                                     size,
-  Objects_Id                                 id,
-  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
-  CORE_message_queue_Submit_types            submit_type,
-  bool                                       wait,
-  Watchdog_Interval                          timeout,
-  ISR_lock_Context                          *lock_context
-);
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _CORE_message_queue_Submit( \
+    the_message_queue, \
+    executing, \
+    buffer, \
+    size, \
+    mp_callout, \
+    mp_id, \
+    submit_type, \
+    wait, \
+    timeout, \
+    lock_context \
+  ) \
+    _CORE_message_queue_Do_submit( \
+      the_message_queue, \
+      executing, \
+      buffer, \
+      size, \
+      mp_callout, \
+      mp_id, \
+      submit_type, \
+      wait, \
+      timeout, \
+      lock_context \
+    )
+#else
+  #define _CORE_message_queue_Submit( \
+    the_message_queue, \
+    executing, \
+    buffer, \
+    size, \
+    mp_callout, \
+    mp_id, \
+    submit_type, \
+    wait, \
+    timeout, \
+    lock_context \
+  ) \
+    _CORE_message_queue_Do_submit( \
+      the_message_queue, \
+      executing, \
+      buffer, \
+      size, \
+      submit_type, \
+      wait, \
+      timeout, \
+      lock_context \
+    )
+#endif
 
 /**
  *  @brief Size a message from the message queue.
@@ -371,58 +452,54 @@ void _CORE_message_queue_Insert_message(
 /**
  * This routine sends a message to the end of the specified message queue.
  */
-RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Send(
-  CORE_message_queue_Control                *the_message_queue,
-  const void                                *buffer,
-  size_t                                     size,
-  Objects_Id                                 id,
-  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
-  bool                                       wait,
-  Watchdog_Interval                          timeout,
-  ISR_lock_Context                          *lock_context
-)
-{
-  return _CORE_message_queue_Submit(
-    the_message_queue,
-    _Thread_Executing,
-    buffer,
-    size,
-    id,
-    api_message_queue_mp_support,
-    CORE_MESSAGE_QUEUE_SEND_REQUEST,
-    wait,     /* sender may block */
-    timeout,  /* timeout interval */
-    lock_context
-  );
-}
+#define _CORE_message_queue_Send( \
+  the_message_queue, \
+  buffer, \
+  size, \
+  mp_callout, \
+  mp_id, \
+  wait, \
+  timeout, \
+  lock_context \
+) \
+  _CORE_message_queue_Submit( \
+    the_message_queue, \
+    _Thread_Executing, \
+    buffer, \
+    size, \
+    mp_callout, \
+    mp_id, \
+    CORE_MESSAGE_QUEUE_SEND_REQUEST, \
+    wait, \
+    timeout, \
+    lock_context \
+  )
 
 /**
  * This routine sends a message to the front of the specified message queue.
  */
-RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Urgent(
-  CORE_message_queue_Control                *the_message_queue,
-  const void                                *buffer,
-  size_t                                     size,
-  Objects_Id                                 id,
-  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
-  bool                                       wait,
-  Watchdog_Interval                          timeout,
-  ISR_lock_Context                          *lock_context
-)
-{
-  return _CORE_message_queue_Submit(
-    the_message_queue,
-    _Thread_Executing,
-    buffer,
-    size,
-    id,
-    api_message_queue_mp_support,
-    CORE_MESSAGE_QUEUE_URGENT_REQUEST,
-    wait,     /* sender may block */
-    timeout,  /* timeout interval */
-    lock_context
- );
-}
+#define _CORE_message_queue_Urgent( \
+  the_message_queue, \
+  buffer, \
+  size, \
+  mp_callout, \
+  mp_id, \
+  wait, \
+  timeout, \
+  lock_context \
+) \
+  _CORE_message_queue_Submit( \
+    the_message_queue, \
+    _Thread_Executing, \
+    buffer, \
+    size, \
+    mp_callout, \
+    mp_id, \
+    CORE_MESSAGE_QUEUE_URGENT_REQUEST, \
+    wait,\
+    timeout, \
+    lock_context \
+ )
 
 RTEMS_INLINE_ROUTINE void _CORE_message_queue_Acquire(
   CORE_message_queue_Control *the_message_queue,
@@ -438,14 +515,6 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Acquire_critical(
 )
 {
   _Thread_queue_Acquire_critical( &the_message_queue->Wait_queue, lock_context );
-
-  #if defined(RTEMS_MULTIPROCESSING)
-    /*
-     * In case RTEMS_MULTIPROCESSING is enabled, then we have to prevent
-     * deletion of the executing thread after the thread queue operations.
-     */
-    _Thread_Dispatch_disable();
-  #endif
 }
 
 RTEMS_INLINE_ROUTINE void _CORE_message_queue_Release(
@@ -454,9 +523,6 @@ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Release(
 )
 {
   _Thread_queue_Release( &the_message_queue->Wait_queue, lock_context );
-  #if defined(RTEMS_MULTIPROCESSING)
-    _Thread_Dispatch_enable( _Per_CPU_Get() );
-  #endif
 }
 
 /**
@@ -576,10 +642,14 @@ RTEMS_INLINE_ROUTINE
            the_message_queue, the_handler, the_argument )
 #endif
 
-RTEMS_INLINE_ROUTINE Thread_Control *_CORE_message_queue_Dequeue_receiver(
+RTEMS_INLINE_ROUTINE Thread_Control *_CORE_message_queue_Do_dequeue_receiver(
   CORE_message_queue_Control      *the_message_queue,
   const void                      *buffer,
   size_t                           size,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout          mp_callout,
+  Objects_Id                       mp_id,
+#endif
   CORE_message_queue_Submit_types  submit_type,
   ISR_lock_Context                *lock_context
 )
@@ -623,12 +693,52 @@ RTEMS_INLINE_ROUTINE Thread_Control *_CORE_message_queue_Dequeue_receiver(
     &the_message_queue->Wait_queue.Queue,
     the_message_queue->operations,
     the_thread,
+    mp_callout,
+    mp_id,
     lock_context
   );
 
   return the_thread;
 }
 
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _CORE_message_queue_Dequeue_receiver( \
+    the_message_queue, \
+    buffer, \
+    size, \
+    mp_callout, \
+    mp_id, \
+    submit_type, \
+    lock_context \
+  ) \
+    _CORE_message_queue_Do_dequeue_receiver( \
+      the_message_queue, \
+      buffer, \
+      size, \
+      mp_callout, \
+      mp_id, \
+      submit_type, \
+      lock_context \
+    )
+#else
+  #define _CORE_message_queue_Dequeue_receiver( \
+    the_message_queue, \
+    buffer, \
+    size, \
+    mp_callout, \
+    mp_id, \
+    submit_type, \
+    lock_context \
+  ) \
+    _CORE_message_queue_Do_dequeue_receiver( \
+      the_message_queue, \
+      buffer, \
+      size, \
+      submit_type, \
+      lock_context \
+    )
+#endif
+
 /** @} */
 
 #ifdef __cplusplus
diff --git a/cpukit/score/include/rtems/score/coremuteximpl.h b/cpukit/score/include/rtems/score/coremuteximpl.h
index 812b6ba..7facabb 100644
--- a/cpukit/score/include/rtems/score/coremuteximpl.h
+++ b/cpukit/score/include/rtems/score/coremuteximpl.h
@@ -34,17 +34,6 @@ extern "C" {
 /**@{**/
 
 /**
- *  @brief Callout which provides to support global/multiprocessor operations.
- *
- *  The following type defines the callout which the API provides
- *  to support global/multiprocessor operations on mutexes.
- */
-typedef void ( *CORE_mutex_API_mp_support_callout )(
-                 Thread_Control *,
-                 Objects_Id
-             );
-
-/**
  *  @brief The possible Mutex handler return statuses.
  *
  *  This enumerated type defines the possible Mutex handler return statuses.
@@ -302,28 +291,41 @@ RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize_body(
          _the_mutex, _executing, _id, _wait, _timeout, _lock_context )
 #endif
 
-/**
- *  @brief Frees a unit to the mutex.
- *
- *  This routine frees a unit to the mutex.  If a task was blocked waiting for
- *  a unit from this mutex, then that task will be readied and the unit
- *  given to that task.  Otherwise, the unit will be returned to the mutex.
- *
- *  @param[in] the_mutex is the mutex to surrender
- *  @param[in] id is the id of the RTEMS Object associated with this mutex
- *  @param[in] api_mutex_mp_support is the routine that will be called when
- *         unblocking a remote mutex
- *  @param[in] lock_context is the interrupt level
- *
- *  @retval an indication of whether the routine succeeded or failed
- */
-CORE_mutex_Status _CORE_mutex_Surrender(
-  CORE_mutex_Control                *the_mutex,
-  Objects_Id                         id,
-  CORE_mutex_API_mp_support_callout  api_mutex_mp_support,
-  ISR_lock_Context                  *lock_context
+CORE_mutex_Status _CORE_mutex_Do_surrender(
+  CORE_mutex_Control      *the_mutex,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout  mp_callout,
+  Objects_Id               mp_id,
+#endif
+  ISR_lock_Context        *lock_context
 );
 
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _CORE_mutex_Surrender( \
+    the_mutex, \
+    mp_callout, \
+    mp_id, \
+    lock_context \
+  ) \
+    _CORE_mutex_Do_surrender( \
+      the_mutex, \
+      mp_callout, \
+      mp_id, \
+      lock_context \
+    )
+#else
+  #define _CORE_mutex_Surrender( \
+    the_mutex, \
+    mp_callout, \
+    mp_id, \
+    lock_context \
+  ) \
+    _CORE_mutex_Do_surrender( \
+      the_mutex, \
+      lock_context \
+    )
+#endif
+
 /* Must be a macro due to the multiprocessing dependent parameters */
 #define _CORE_mutex_Flush( \
   the_mutex, \
diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h
index bde3e5b..79d907c 100644
--- a/cpukit/score/include/rtems/score/coresemimpl.h
+++ b/cpukit/score/include/rtems/score/coresemimpl.h
@@ -68,15 +68,6 @@ typedef enum {
 #define CORE_SEMAPHORE_STATUS_LAST CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED
 
 /**
- *  The following type defines the callout which the API provides
- *  to support global/multiprocessor operations on semaphores.
- */
-typedef void ( *CORE_semaphore_API_mp_support_callout )(
-                 Thread_Control *,
-                 Objects_Id
-             );
-
-/**
  *  @brief Initialize the semaphore based on the parameters passed.
  *
  *  This package is the implementation of the CORE Semaphore Handler.
@@ -102,28 +93,13 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
   _Thread_queue_Destroy( &the_semaphore->Wait_queue );
 }
 
-/**
- *  @brief Surrender a unit to a semaphore.
- *
- *  This routine frees a unit to the semaphore.  If a task was blocked waiting
- *  for a unit from this semaphore, then that task will be readied and the unit
- *  given to that task.  Otherwise, the unit will be returned to the semaphore.
- *
- *  @param[in] the_semaphore is the semaphore to surrender
- *  @param[in] id is the Id of the API level Semaphore object associated
- *         with this instance of a SuperCore Semaphore
- *  @param[in] api_semaphore_mp_support is the routine to invoke if the
- *         thread unblocked is remote
- *  @param[in] lock_context is a temporary variable used to contain the ISR
- *        disable level cookie
- *
- *  @retval an indication of whether the routine succeeded or failed
- */
-RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender(
-  CORE_semaphore_Control                *the_semaphore,
-  Objects_Id                             id,
-  CORE_semaphore_API_mp_support_callout  api_semaphore_mp_support,
-  ISR_lock_Context                      *lock_context
+RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Do_surrender(
+  CORE_semaphore_Control  *the_semaphore,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout  mp_callout,
+  Objects_Id               mp_id,
+#endif
+  ISR_lock_Context        *lock_context
 )
 {
   Thread_Control *the_thread;
@@ -138,23 +114,14 @@ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender(
     the_semaphore->operations
   );
   if ( the_thread != NULL ) {
-#if defined(RTEMS_MULTIPROCESSING)
-    _Thread_Dispatch_disable();
-#endif
-
     _Thread_queue_Extract_critical(
       &the_semaphore->Wait_queue.Queue,
       the_semaphore->operations,
       the_thread,
+      mp_callout,
+      mp_id,
       lock_context
     );
-
-#if defined(RTEMS_MULTIPROCESSING)
-    if ( !_Objects_Is_local_id( the_thread->Object.id ) )
-      (*api_semaphore_mp_support) ( the_thread, id );
-
-    _Thread_Dispatch_enable( _Per_CPU_Get() );
-#endif
   } else {
     if ( the_semaphore->count < UINT32_MAX )
       the_semaphore->count += 1;
@@ -167,6 +134,49 @@ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender(
   return status;
 }
 
+/**
+ *  @brief Surrender a unit to a semaphore.
+ *
+ *  This routine frees a unit to the semaphore.  If a task was blocked waiting
+ *  for a unit from this semaphore, then that task will be readied and the unit
+ *  given to that task.  Otherwise, the unit will be returned to the semaphore.
+ *
+ *  @param[in] the_semaphore is the semaphore to surrender
+ *  @param[in] mp_callout is the routine to invoke if the
+ *         thread unblocked is remote
+ *  @param[in] mp_id is the Id of the API level Semaphore object associated
+ *         with this instance of a SuperCore Semaphore
+ *  @param[in] lock_context is a temporary variable used to contain the ISR
+ *        disable level cookie
+ *
+ *  @retval an indication of whether the routine succeeded or failed
+ */
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _CORE_semaphore_Surrender( \
+    the_semaphore, \
+    mp_callout, \
+    mp_id, \
+    lock_context \
+  ) \
+    _CORE_semaphore_Do_surrender( \
+      the_semaphore, \
+      mp_callout, \
+      mp_id, \
+      lock_context \
+    )
+#else
+  #define _CORE_semaphore_Surrender( \
+    the_semaphore, \
+    mp_callout, \
+    mp_id, \
+    lock_context \
+  ) \
+    _CORE_semaphore_Do_surrender( \
+      the_semaphore, \
+      lock_context \
+    )
+#endif
+
 /* Must be a macro due to the multiprocessing dependent parameters */
 #define _CORE_semaphore_Flush( \
   the_semaphore, \
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 949e8ca..7bb65e4 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -418,8 +418,19 @@ typedef struct {
 #if defined(RTEMS_MULTIPROCESSING)
   /** This field is the received response packet in an MP system. */
   MP_packet_Prefix        *receive_packet;
-#endif
      /****************** end of common block ********************/
+
+  /**
+   * @brief Thread queue callout for _Thread_queue_Enqueue_critical().
+   */
+  Thread_queue_MP_callout  thread_queue_callout;
+
+  /**
+   * @brief Thread queue object identifier for
+   * _Thread_queue_Enqueue_critical().
+   */
+  Objects_Id               thread_queue_id;
+
   /** This field is used to manage the set of proxies in the system. */
   Chain_Node               Active;
 
@@ -431,6 +442,7 @@ typedef struct {
    * same storage place for the thread queue heads.
    */
   Thread_queue_Heads       Thread_queue_heads[ RTEMS_ZERO_LENGTH_ARRAY ];
+#endif
 }   Thread_Proxy_control;
 
 /**
diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h
index fbd5329..fb20148 100644
--- a/cpukit/score/include/rtems/score/threadq.h
+++ b/cpukit/score/include/rtems/score/threadq.h
@@ -21,6 +21,7 @@
 
 #include <rtems/score/chain.h>
 #include <rtems/score/isrlock.h>
+#include <rtems/score/object.h>
 #include <rtems/score/priority.h>
 #include <rtems/score/rbtree.h>
 
@@ -41,6 +42,21 @@ extern "C" {
 
 typedef struct _Thread_Control Thread_Control;
 
+#if defined(RTEMS_MULTIPROCESSING)
+/**
+ * @brief Multiprocessing (MP) support callout for thread queue operations.
+ *
+ * @param the_proxy The thread proxy of the thread queue operation.  A thread
+ *   control is actually a thread proxy if and only if
+ *   _Objects_Is_local_id( the_proxy->Object.id ) is false.
+ * @param mp_id Object identifier of the object containing the thread queue.
+ */
+typedef void ( *Thread_queue_MP_callout )(
+  Thread_Control *the_proxy,
+  Objects_Id      mp_id
+);
+#endif
+
 /**
  * @brief Thread priority queue.
  */
diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h
index 76f29d3..d56be79 100644
--- a/cpukit/score/include/rtems/score/threadqimpl.h
+++ b/cpukit/score/include/rtems/score/threadqimpl.h
@@ -153,20 +153,15 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
   );
 }
 
+Thread_Control *_Thread_queue_Do_dequeue(
+  Thread_queue_Control          *the_thread_queue,
+  const Thread_queue_Operations *operations
 #if defined(RTEMS_MULTIPROCESSING)
-/**
- * @brief Multiprocessing (MP) support callout for thread queue operations.
- *
- * @param the_proxy The thread proxy of the thread queue operation.  A thread
- *   control is actually a thread proxy if and only if
- *   _Objects_Is_local_id( the_proxy->Object.id ) is false.
- * @param mp_id Object identifier of the object containing the thread queue.
- */
-typedef void ( *Thread_queue_MP_callout )(
-  Thread_Control *the_proxy,
-  Objects_Id      mp_id
-);
+  ,
+  Thread_queue_MP_callout        mp_callout,
+  Objects_Id                     mp_id
 #endif
+);
 
 /**
  *  @brief Gets a pointer to a thread waiting on the_thread_queue.
@@ -179,10 +174,31 @@ typedef void ( *Thread_queue_MP_callout )(
  *  - INTERRUPT LATENCY:
  *    + single case
  */
-Thread_Control *_Thread_queue_Dequeue(
-  Thread_queue_Control          *the_thread_queue,
-  const Thread_queue_Operations *operations
-);
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _Thread_queue_Dequeue( \
+    the_thread_queue, \
+    operations, \
+    mp_callout, \
+    mp_id \
+  ) \
+    _Thread_queue_Do_dequeue( \
+      the_thread_queue, \
+      operations, \
+      mp_callout, \
+      mp_id \
+    )
+#else
+  #define _Thread_queue_Dequeue( \
+    the_thread_queue, \
+    operations, \
+    mp_callout, \
+    mp_id \
+  ) \
+    _Thread_queue_Do_dequeue( \
+      the_thread_queue, \
+      operations \
+    )
+#endif
 
 /**
  * @brief Blocks the thread and places it on the thread queue.
@@ -283,6 +299,17 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
   );
 }
 
+bool _Thread_queue_Do_extract_locked(
+  Thread_queue_Queue            *queue,
+  const Thread_queue_Operations *operations,
+  Thread_Control                *the_thread
+#if defined(RTEMS_MULTIPROCESSING)
+  ,
+  Thread_queue_MP_callout        mp_callout,
+  Objects_Id                     mp_id
+#endif
+);
+
 /**
  * @brief Extracts the thread from the thread queue, restores the default wait
  * operations and restores the default thread lock.
@@ -293,6 +320,11 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
  * @param[in] queue The actual thread queue.
  * @param[in] operations The thread queue operations.
  * @param[in] the_thread The thread to extract.
+ * @param[in] mp_callout Callout to unblock the thread in case it is actually a
+ *   thread proxy.  This parameter is only used on multiprocessing
+ *   configurations.
+ * @param[in] mp_id Object identifier of the object containing the thread
+ *   queue.  This parameter is only used on multiprocessing configurations.
  *
  * @return Returns the unblock indicator for _Thread_queue_Unblock_critical().
  * True indicates, that this thread must be unblocked by the scheduler later in
@@ -302,10 +334,45 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
  * since this thread may already block on another resource in an SMP
  * configuration.
  */
-bool _Thread_queue_Extract_locked(
-  Thread_queue_Queue            *queue,
-  const Thread_queue_Operations *operations,
-  Thread_Control                *the_thread
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _Thread_queue_Extract_locked( \
+    unblock, \
+    queue, \
+    the_thread, \
+    mp_callout, \
+    mp_id \
+  ) \
+    _Thread_queue_Do_extract_locked( \
+      unblock, \
+      queue, \
+      the_thread, \
+      mp_callout, \
+      mp_id \
+    )
+#else
+  #define _Thread_queue_Extract_locked( \
+    unblock, \
+    queue, \
+    the_thread, \
+    mp_callout, \
+    mp_id \
+  ) \
+    _Thread_queue_Do_extract_locked( \
+      unblock, \
+      queue, \
+      the_thread \
+    )
+#endif
+
+void _Thread_queue_Do_unblock_critical(
+  bool                     unblock,
+  Thread_queue_Queue      *queue,
+  Thread_Control          *the_thread,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout  mp_callout,
+  Objects_Id               mp_id,
+#endif
+  ISR_lock_Context        *lock_context
 );
 
 /**
@@ -320,13 +387,56 @@ bool _Thread_queue_Extract_locked(
  * _Thread_queue_Extract_locked().
  * @param[in] queue The actual thread queue.
  * @param[in] the_thread The thread to extract.
+ * @param[in] mp_callout Callout to unblock the thread in case it is actually a
+ *   thread proxy.  This parameter is only used on multiprocessing
+ *   configurations.
+ * @param[in] mp_id Object identifier of the object containing the thread
+ *   queue.  This parameter is only used on multiprocessing configurations.
  * @param[in] lock_context The lock context of the lock acquire.
  */
-void _Thread_queue_Unblock_critical(
-  bool                unblock,
-  Thread_queue_Queue *queue,
-  Thread_Control     *the_thread,
-  ISR_lock_Context   *lock_context
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _Thread_queue_Unblock_critical( \
+    unblock, \
+    queue, \
+    the_thread, \
+    mp_callout, \
+    mp_id, \
+    lock_context \
+  ) \
+    _Thread_queue_Do_unblock_critical( \
+      unblock, \
+      queue, \
+      the_thread, \
+      mp_callout, \
+      mp_id, \
+      lock_context \
+    )
+#else
+  #define _Thread_queue_Unblock_critical( \
+    unblock, \
+    queue, \
+    the_thread, \
+    mp_callout, \
+    mp_id, \
+    lock_context \
+  ) \
+    _Thread_queue_Do_unblock_critical( \
+      unblock, \
+      queue, \
+      the_thread, \
+      lock_context \
+    )
+#endif
+
+void _Thread_queue_Do_extract_critical(
+  Thread_queue_Queue            *queue,
+  const Thread_queue_Operations *operations,
+  Thread_Control                *the_thread,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout        mp_callout,
+  Objects_Id                     mp_id,
+#endif
+  ISR_lock_Context              *lock_context
 );
 
 /**
@@ -364,6 +474,8 @@ void _Thread_queue_Unblock_critical(
  *       &mutex->Queue.Queue,
  *       mutex->Queue.operations,
  *       first,
+ *       NULL,
+ *       0,
  *       &lock_context
  *   );
  * }
@@ -372,14 +484,46 @@ void _Thread_queue_Unblock_critical(
  * @param[in] queue The actual thread queue.
  * @param[in] operations The thread queue operations.
  * @param[in] the_thread The thread to extract.
+ * @param[in] mp_callout Callout to unblock the thread in case it is actually a
+ *   thread proxy.  This parameter is only used on multiprocessing
+ *   configurations.
+ * @param[in] mp_id Object identifier of the object containing the thread
+ *   queue.  This parameter is only used on multiprocessing configurations.
  * @param[in] lock_context The lock context of the lock acquire.
  */
-void _Thread_queue_Extract_critical(
-  Thread_queue_Queue            *queue,
-  const Thread_queue_Operations *operations,
-  Thread_Control                *the_thread,
-  ISR_lock_Context              *lock_context
-);
+#if defined(RTEMS_MULTIPROCESSING)
+  #define _Thread_queue_Extract_critical( \
+    queue, \
+    operations, \
+    the_thread, \
+    mp_callout, \
+    mp_id, \
+    lock_context \
+  ) \
+    _Thread_queue_Do_extract_critical( \
+      queue, \
+      operations, \
+      the_thread, \
+      mp_callout, \
+      mp_id, \
+      lock_context \
+    )
+#else
+  #define _Thread_queue_Extract_critical( \
+    queue, \
+    operations, \
+    the_thread, \
+    mp_callout, \
+    mp_id, \
+    lock_context \
+  ) \
+    _Thread_queue_Do_extract_critical( \
+      queue, \
+      operations, \
+      the_thread, \
+      lock_context \
+    )
+#endif
 
 /**
  *  @brief Extracts thread from thread queue.
@@ -574,6 +718,13 @@ RBTree_Compare_result _Thread_queue_Compare_priority(
   const RBTree_Node *right
 );
 
+#if defined(RTEMS_MULTIPROCESSING)
+void _Thread_queue_MP_callout_do_nothing(
+  Thread_Control *the_proxy,
+  Objects_Id      mp_id
+);
+#endif
+
 extern const Thread_queue_Operations _Thread_queue_Operations_default;
 
 extern const Thread_queue_Operations _Thread_queue_Operations_FIFO;
diff --git a/cpukit/score/src/apimutexunlock.c b/cpukit/score/src/apimutexunlock.c
index 04657dd..3545377 100644
--- a/cpukit/score/src/apimutexunlock.c
+++ b/cpukit/score/src/apimutexunlock.c
@@ -35,8 +35,8 @@ void _API_Mutex_Unlock( API_Mutex_Control *the_mutex )
   _ISR_lock_ISR_disable( &lock_context );
   _CORE_mutex_Surrender(
     &the_mutex->Mutex,
-    the_mutex->Object.id,
     NULL,
+    0,
     &lock_context
   );
 
diff --git a/cpukit/score/src/condition.c b/cpukit/score/src/condition.c
index 4206819..da3d133 100644
--- a/cpukit/score/src/condition.c
+++ b/cpukit/score/src/condition.c
@@ -257,7 +257,9 @@ static int _Condition_Wake( struct _Condition_Control *_condition, int count )
     do_unblock = _Thread_queue_Extract_locked(
       &condition->Queue.Queue,
       operations,
-      first
+      first,
+      NULL,
+      0
     );
     if (do_unblock) {
       _Chain_Append_unprotected( &unblock, &first->Wait.Node.Chain );
diff --git a/cpukit/score/src/corebarrierrelease.c b/cpukit/score/src/corebarrierrelease.c
index ba02301..4458064 100644
--- a/cpukit/score/src/corebarrierrelease.c
+++ b/cpukit/score/src/corebarrierrelease.c
@@ -23,24 +23,12 @@
 #include <rtems/score/objectimpl.h>
 #include <rtems/score/threadqimpl.h>
 
-static Thread_Control *_CORE_barrier_Dequeue(
-  CORE_barrier_Control *the_barrier
-)
-{
-  return _Thread_queue_Dequeue(
-    &the_barrier->Wait_queue,
-    CORE_BARRIER_TQ_OPERATIONS
-  );
-}
-
-uint32_t _CORE_barrier_Release(
-  CORE_barrier_Control                *the_barrier,
+uint32_t _CORE_barrier_Do_release(
+  CORE_barrier_Control    *the_barrier
 #if defined(RTEMS_MULTIPROCESSING)
-  Objects_Id                           id,
-  CORE_barrier_API_mp_support_callout  api_barrier_mp_support
-#else
-  Objects_Id                           id RTEMS_UNUSED,
-  CORE_barrier_API_mp_support_callout  api_barrier_mp_support RTEMS_UNUSED
+  ,
+  Thread_queue_MP_callout  mp_callout,
+  Objects_Id               mp_id
 #endif
 )
 {
@@ -48,11 +36,16 @@ uint32_t _CORE_barrier_Release(
   uint32_t        count;
 
   count = 0;
-  while ( ( the_thread = _CORE_barrier_Dequeue( the_barrier ) ) ) {
-#if defined(RTEMS_MULTIPROCESSING)
-    if ( !_Objects_Is_local_id( the_thread->Object.id ) )
-      (*api_barrier_mp_support) ( the_thread, id );
-#endif
+  while (
+    (
+      the_thread = _Thread_queue_Dequeue(
+        &the_barrier->Wait_queue,
+        CORE_BARRIER_TQ_OPERATIONS,
+        mp_callout,
+        mp_id
+      )
+    )
+  ) {
     count++;
   }
   the_barrier->number_of_waiting_threads = 0;
diff --git a/cpukit/score/src/corebarrierwait.c b/cpukit/score/src/corebarrierwait.c
index 52cbe74..689ead0 100644
--- a/cpukit/score/src/corebarrierwait.c
+++ b/cpukit/score/src/corebarrierwait.c
@@ -23,13 +23,16 @@
 #include <rtems/score/statesimpl.h>
 #include <rtems/score/threadqimpl.h>
 
-void _CORE_barrier_Wait(
-  CORE_barrier_Control                *the_barrier,
-  Thread_Control                      *executing,
-  Objects_Id                           id,
-  bool                                 wait,
-  Watchdog_Interval                    timeout,
-  CORE_barrier_API_mp_support_callout  api_barrier_mp_support
+void _CORE_barrier_Do_wait(
+  CORE_barrier_Control    *the_barrier,
+  Thread_Control          *executing,
+  bool                     wait,
+  Watchdog_Interval        timeout
+#if defined(RTEMS_MULTIPROCESSING)
+  ,
+  Thread_queue_MP_callout  mp_callout,
+  Objects_Id               mp_id
+#endif
 )
 {
   ISR_lock_Context lock_context;
@@ -42,7 +45,7 @@ void _CORE_barrier_Wait(
 	 the_barrier->Attributes.maximum_count) {
       executing->Wait.return_code = CORE_BARRIER_STATUS_AUTOMATICALLY_RELEASED;
       _Thread_queue_Release( &the_barrier->Wait_queue, &lock_context );
-      _CORE_barrier_Release( the_barrier, id, api_barrier_mp_support );
+      _CORE_barrier_Release( the_barrier, mp_callout, mp_id );
       return;
     }
   }
diff --git a/cpukit/score/src/coremsgbroadcast.c b/cpukit/score/src/coremsgbroadcast.c
index 95a8650..9a863ff 100644
--- a/cpukit/score/src/coremsgbroadcast.c
+++ b/cpukit/score/src/coremsgbroadcast.c
@@ -21,19 +21,16 @@
 #include <rtems/score/coremsgimpl.h>
 #include <rtems/score/objectimpl.h>
 
-CORE_message_queue_Status _CORE_message_queue_Broadcast(
-  CORE_message_queue_Control                *the_message_queue,
-  const void                                *buffer,
-  size_t                                     size,
-  #if defined(RTEMS_MULTIPROCESSING)
-    Objects_Id                                 id,
-    CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
-  #else
-    Objects_Id                                 id RTEMS_UNUSED,
-    CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support RTEMS_UNUSED,
-  #endif
-  uint32_t                                  *count,
-  ISR_lock_Context                          *lock_context
+CORE_message_queue_Status _CORE_message_queue_Do_broadcast(
+  CORE_message_queue_Control *the_message_queue,
+  const void                 *buffer,
+  size_t                      size,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout     mp_callout,
+  Objects_Id                  mp_id,
+#endif
+  uint32_t                   *count,
+  ISR_lock_Context           *lock_context
 )
 {
   Thread_Control             *the_thread;
@@ -54,6 +51,8 @@ CORE_message_queue_Status _CORE_message_queue_Broadcast(
         the_message_queue,
         buffer,
         size,
+        mp_callout,
+        mp_id,
         0,
         lock_context
       )
@@ -61,11 +60,6 @@ CORE_message_queue_Status _CORE_message_queue_Broadcast(
   ) {
     number_broadcasted += 1;
 
-#if defined(RTEMS_MULTIPROCESSING)
-    if ( !_Objects_Is_local_id( the_thread->Object.id ) )
-      (*api_message_queue_mp_support) ( the_thread, id );
-#endif
-
     _CORE_message_queue_Acquire( the_message_queue, lock_context );
   }
 
diff --git a/cpukit/score/src/coremsgseize.c b/cpukit/score/src/coremsgseize.c
index 34a3c50..5e14918 100644
--- a/cpukit/score/src/coremsgseize.c
+++ b/cpukit/score/src/coremsgseize.c
@@ -27,14 +27,14 @@
 #include <rtems/score/wkspace.h>
 
 void _CORE_message_queue_Seize(
-  CORE_message_queue_Control      *the_message_queue,
-  Thread_Control                  *executing,
-  Objects_Id                       id,
-  void                            *buffer,
-  size_t                          *size_p,
-  bool                             wait,
-  Watchdog_Interval                timeout,
-  ISR_lock_Context                *lock_context
+  CORE_message_queue_Control *the_message_queue,
+  Thread_Control             *executing,
+  Objects_Id                  id,
+  void                       *buffer,
+  size_t                     *size_p,
+  bool                        wait,
+  Watchdog_Interval           timeout,
+  ISR_lock_Context           *lock_context
 )
 {
   CORE_message_queue_Buffer_control *the_message;
@@ -111,11 +111,10 @@ void _CORE_message_queue_Seize(
         &the_message_queue->Wait_queue.Queue,
         the_message_queue->operations,
         the_thread,
+        NULL,
+        0,
         lock_context
       );
-      #if defined(RTEMS_MULTIPROCESSING)
-        _Thread_Dispatch_enable( _Per_CPU_Get() );
-      #endif
       return;
     }
     #endif
@@ -140,7 +139,4 @@ void _CORE_message_queue_Seize(
     CORE_MESSAGE_QUEUE_STATUS_TIMEOUT,
     lock_context
   );
-  #if defined(RTEMS_MULTIPROCESSING)
-    _Thread_Dispatch_enable( _Per_CPU_Get() );
-  #endif
 }
diff --git a/cpukit/score/src/coremsgsubmit.c b/cpukit/score/src/coremsgsubmit.c
index 02de12f..f63fa39 100644
--- a/cpukit/score/src/coremsgsubmit.c
+++ b/cpukit/score/src/coremsgsubmit.c
@@ -25,21 +25,19 @@
 #include <rtems/score/statesimpl.h>
 #include <rtems/score/wkspace.h>
 
-CORE_message_queue_Status _CORE_message_queue_Submit(
-  CORE_message_queue_Control                *the_message_queue,
-  Thread_Control                            *executing,
-  const void                                *buffer,
-  size_t                                     size,
-  Objects_Id                                 id,
-  #if defined(RTEMS_MULTIPROCESSING)
-    CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
-  #else
-    CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support  RTEMS_UNUSED,
-  #endif
-  CORE_message_queue_Submit_types            submit_type,
-  bool                                       wait,
-  Watchdog_Interval                          timeout,
-  ISR_lock_Context                          *lock_context
+CORE_message_queue_Status _CORE_message_queue_Do_submit(
+  CORE_message_queue_Control       *the_message_queue,
+  Thread_Control                   *executing,
+  const void                       *buffer,
+  size_t                            size,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout           mp_callout,
+  Objects_Id                        mp_id,
+#endif
+  CORE_message_queue_Submit_types   submit_type,
+  bool                              wait,
+  Watchdog_Interval                 timeout,
+  ISR_lock_Context                 *lock_context
 )
 {
   CORE_message_queue_Buffer_control *the_message;
@@ -60,16 +58,12 @@ CORE_message_queue_Status _CORE_message_queue_Submit(
     the_message_queue,
     buffer,
     size,
+    mp_callout,
+    mp_id,
     submit_type,
     lock_context
   );
   if ( the_thread != NULL ) {
-    #if defined(RTEMS_MULTIPROCESSING)
-      if ( !_Objects_Is_local_id( the_thread->Object.id ) )
-        (*api_message_queue_mp_support) ( the_thread, id );
-
-      _Thread_Dispatch_enable( _Per_CPU_Get() );
-    #endif
     return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
   }
 
@@ -139,10 +133,6 @@ CORE_message_queue_Status _CORE_message_queue_Submit(
       CORE_MESSAGE_QUEUE_STATUS_TIMEOUT,
       lock_context
     );
-    #if defined(RTEMS_MULTIPROCESSING)
-      _Thread_Dispatch_enable( _Per_CPU_Get() );
-    #endif
-
     return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT;
   #endif
 }
diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c
index da21d4b..1858f9c 100644
--- a/cpukit/score/src/coremutexsurrender.c
+++ b/cpukit/score/src/coremutexsurrender.c
@@ -68,33 +68,13 @@
     CORE_MUTEX_STATUS_SUCCESSFUL
 #endif
 
-/*
- *  _CORE_mutex_Surrender
- *
- *  This routine frees a unit to the mutex.  If a task was blocked waiting for
- *  a unit from this mutex, then that task will be readied and the unit
- *  given to that task.  Otherwise, the unit will be returned to the mutex.
- *
- *  Input parameters:
- *    the_mutex            - the mutex to be flushed
- *    id                   - id of parent mutex
- *    api_mutex_mp_support - api dependent MP support actions
- *
- *  Output parameters:
- *    CORE_MUTEX_STATUS_SUCCESSFUL - if successful
- *    core error code              - if unsuccessful
- */
-
-CORE_mutex_Status _CORE_mutex_Surrender(
-  CORE_mutex_Control                *the_mutex,
+CORE_mutex_Status _CORE_mutex_Do_surrender(
+  CORE_mutex_Control      *the_mutex,
 #if defined(RTEMS_MULTIPROCESSING)
-  Objects_Id                         id,
-  CORE_mutex_API_mp_support_callout  api_mutex_mp_support,
-#else
-  Objects_Id                         id RTEMS_UNUSED,
-  CORE_mutex_API_mp_support_callout  api_mutex_mp_support RTEMS_UNUSED,
+  Thread_queue_MP_callout  mp_callout,
+  Objects_Id               mp_id,
 #endif
-  ISR_lock_Context                  *lock_context
+  ISR_lock_Context        *lock_context
 )
 {
   Thread_Control *the_thread;
@@ -199,12 +179,12 @@ CORE_mutex_Status _CORE_mutex_Surrender(
     unblock = _Thread_queue_Extract_locked(
       &the_mutex->Wait_queue.Queue,
       the_mutex->operations,
-      the_thread
+      the_thread,
+      mp_callout,
+      mp_id
     );
 
 #if defined(RTEMS_MULTIPROCESSING)
-    _Thread_Dispatch_disable();
-
     if ( _Objects_Is_local_id( the_thread->Object.id ) )
 #endif
     {
@@ -232,16 +212,10 @@ CORE_mutex_Status _CORE_mutex_Surrender(
       unblock,
       &the_mutex->Wait_queue.Queue,
       the_thread,
+      mp_callout,
+      mp_id,
       lock_context
     );
-
-#if defined(RTEMS_MULTIPROCESSING)
-    if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
-      ( *api_mutex_mp_support)( the_thread, id );
-    }
-
-    _Thread_Dispatch_enable( _Per_CPU_Get() );
-#endif
   } else {
     _Thread_queue_Release( &the_mutex->Wait_queue, lock_context );
   }
diff --git a/cpukit/score/src/corerwlockrelease.c b/cpukit/score/src/corerwlockrelease.c
index 36fcf76..142ae65 100644
--- a/cpukit/score/src/corerwlockrelease.c
+++ b/cpukit/score/src/corerwlockrelease.c
@@ -66,7 +66,9 @@ CORE_RWLock_Status _CORE_RWLock_Release(
 
   next = _Thread_queue_Dequeue(
     &the_rwlock->Wait_queue,
-    CORE_RWLOCK_TQ_OPERATIONS
+    CORE_RWLOCK_TQ_OPERATIONS,
+    NULL,
+    0
   );
 
   if ( next ) {
diff --git a/cpukit/score/src/futex.c b/cpukit/score/src/futex.c
index 2ec38a3..73d48fd 100644
--- a/cpukit/score/src/futex.c
+++ b/cpukit/score/src/futex.c
@@ -133,7 +133,9 @@ static __attribute__((noinline)) int _Futex_Wake_slow(
     do_unblock = _Thread_queue_Extract_locked(
       &futex->Queue.Queue,
       operations,
-      first
+      first,
+      NULL,
+      0
     );
     if (do_unblock) {
       _Chain_Append_unprotected( &unblock, &first->Wait.Node.Chain );
diff --git a/cpukit/score/src/mutex.c b/cpukit/score/src/mutex.c
index b4b6d44..5588926 100644
--- a/cpukit/score/src/mutex.c
+++ b/cpukit/score/src/mutex.c
@@ -145,13 +145,17 @@ static void _Mutex_Release_slow(
     unblock = _Thread_queue_Extract_locked(
       &mutex->Queue.Queue,
       operations,
-      first
+      first,
+      NULL,
+      0
     );
     _Thread_queue_Boost_priority( &mutex->Queue.Queue, first );
     _Thread_queue_Unblock_critical(
       unblock,
       &mutex->Queue.Queue,
       first,
+      NULL,
+      0,
       lock_context
     );
   } else {
diff --git a/cpukit/score/src/semaphore.c b/cpukit/score/src/semaphore.c
index 94e5209..ae1b5c7 100644
--- a/cpukit/score/src/semaphore.c
+++ b/cpukit/score/src/semaphore.c
@@ -133,6 +133,8 @@ void _Semaphore_Post( struct _Semaphore_Control *_sem )
       &sem->Queue.Queue,
       operations,
       first,
+      NULL,
+      0,
       &lock_context
     );
   }
diff --git a/cpukit/score/src/threadmp.c b/cpukit/score/src/threadmp.c
index 33c9078..8ba4d49 100644
--- a/cpukit/score/src/threadmp.c
+++ b/cpukit/score/src/threadmp.c
@@ -102,6 +102,8 @@ Thread_Control *_Thread_MP_Allocate_proxy (
     the_proxy->Wait.return_code             = executing->Wait.return_code;
     the_proxy->Wait.timeout_code            = executing->Wait.timeout_code;
 
+    the_proxy->thread_queue_callout = _Thread_queue_MP_callout_do_nothing;
+
     _Chain_Append( &_Thread_MP_Active_proxies, &the_proxy->Active );
 
     return the_thread;
diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c
index f8f18ed..b3ccbd6 100644
--- a/cpukit/score/src/threadq.c
+++ b/cpukit/score/src/threadq.c
@@ -86,3 +86,13 @@ void _Thread_queue_Initialize( Thread_queue_Control *the_thread_queue )
   _SMP_lock_Stats_initialize( &the_thread_queue->Lock_stats, "Thread Queue" );
 #endif
 }
+
+#if defined(RTEMS_MULTIPROCESSING)
+void _Thread_queue_MP_callout_do_nothing(
+  Thread_Control *the_proxy,
+  Objects_Id      mp_id
+)
+{
+  /* Do nothing */
+}
+#endif
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c
index 71e93c2..ce72008 100644
--- a/cpukit/score/src/threadqenqueue.c
+++ b/cpukit/score/src/threadqenqueue.c
@@ -33,18 +33,6 @@
 #define THREAD_QUEUE_READY_AGAIN \
   (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_READY_AGAIN)
 
-static void _Thread_queue_Unblock( Thread_Control *the_thread )
-{
-  _Thread_Timer_remove( the_thread );
-  _Thread_Unblock( the_thread );
-
-#if defined(RTEMS_MULTIPROCESSING)
-  if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
-    _Thread_MP_Free_proxy( the_thread );
-  }
-#endif
-}
-
 void _Thread_queue_Enqueue_critical(
   Thread_queue_Queue            *queue,
   const Thread_queue_Operations *operations,
@@ -99,21 +87,56 @@ void _Thread_queue_Enqueue_critical(
     THREAD_QUEUE_BLOCKED
   );
   if ( !success ) {
-    _Thread_queue_Unblock( the_thread );
+    _Thread_Timer_remove( the_thread );
+
+#if defined(RTEMS_MULTIPROCESSING)
+    if ( _Objects_Is_local_id( the_thread->Object.id ) ) {
+      _Thread_Unblock( the_thread );
+    } else {
+      Thread_Proxy_control *the_proxy;
+
+      the_proxy = (Thread_Proxy_control *) the_thread;
+      ( *the_proxy->thread_queue_callout )(
+        the_thread,
+        the_proxy->thread_queue_id
+      );
+
+      _Thread_MP_Free_proxy( the_thread );
+    }
+#else
+    _Thread_Unblock( the_thread );
+#endif
   }
 
   _Thread_Dispatch_enable( cpu_self );
 }
 
-bool _Thread_queue_Extract_locked(
+bool _Thread_queue_Do_extract_locked(
   Thread_queue_Queue            *queue,
   const Thread_queue_Operations *operations,
   Thread_Control                *the_thread
+#if defined(RTEMS_MULTIPROCESSING)
+  ,
+  Thread_queue_MP_callout        mp_callout,
+  Objects_Id                     mp_id
+#endif
 )
 {
   bool success;
   bool unblock;
 
+#if defined(RTEMS_MULTIPROCESSING)
+  if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
+    Thread_Proxy_control *the_proxy;
+
+    _Assert( mp_callout != NULL );
+
+    the_proxy = (Thread_Proxy_control *) the_thread;
+    the_proxy->thread_queue_callout = mp_callout;
+    the_proxy->thread_queue_id = mp_id;
+  }
+#endif
+
   ( *operations->extract )( queue, the_thread );
 
   /*
@@ -140,11 +163,15 @@ bool _Thread_queue_Extract_locked(
   return unblock;
 }
 
-void _Thread_queue_Unblock_critical(
-  bool                unblock,
-  Thread_queue_Queue *queue,
-  Thread_Control     *the_thread,
-  ISR_lock_Context   *lock_context
+void _Thread_queue_Do_unblock_critical(
+  bool                     unblock,
+  Thread_queue_Queue      *queue,
+  Thread_Control          *the_thread,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout  mp_callout,
+  Objects_Id               mp_id,
+#endif
+  ISR_lock_Context        *lock_context
 )
 {
   if ( unblock ) {
@@ -153,7 +180,18 @@ void _Thread_queue_Unblock_critical(
     cpu_self = _Thread_Dispatch_disable_critical( lock_context );
     _Thread_queue_Queue_release( queue, lock_context );
 
-    _Thread_queue_Unblock( the_thread );
+    _Thread_Timer_remove( the_thread );
+
+#if defined(RTEMS_MULTIPROCESSING)
+    if ( _Objects_Is_local_id( the_thread->Object.id ) ) {
+      _Thread_Unblock( the_thread );
+    } else {
+      ( *mp_callout )( the_thread, mp_id );
+      _Thread_MP_Free_proxy( the_thread );
+    }
+#else
+    _Thread_Unblock( the_thread );
+#endif
 
     _Thread_Dispatch_enable( cpu_self );
   } else {
@@ -161,17 +199,35 @@ void _Thread_queue_Unblock_critical(
   }
 }
 
-void _Thread_queue_Extract_critical(
+void _Thread_queue_Do_extract_critical(
   Thread_queue_Queue            *queue,
   const Thread_queue_Operations *operations,
   Thread_Control                *the_thread,
+#if defined(RTEMS_MULTIPROCESSING)
+  Thread_queue_MP_callout        mp_callout,
+  Objects_Id                     mp_id,
+#endif
   ISR_lock_Context              *lock_context
 )
 {
   bool unblock;
 
-  unblock = _Thread_queue_Extract_locked( queue, operations, the_thread );
-  _Thread_queue_Unblock_critical( unblock, queue, the_thread, lock_context );
+  unblock = _Thread_queue_Extract_locked(
+    queue,
+    operations,
+    the_thread,
+    mp_callout,
+    mp_id
+  );
+
+  _Thread_queue_Unblock_critical(
+    unblock,
+    queue,
+    the_thread,
+    mp_callout,
+    mp_id,
+    lock_context
+  );
 }
 
 void _Thread_queue_Extract( Thread_Control *the_thread )
@@ -191,6 +247,8 @@ void _Thread_queue_Extract( Thread_Control *the_thread )
       queue,
       the_thread->Wait.operations,
       the_thread,
+      _Thread_queue_MP_callout_do_nothing,
+      0,
       &lock_context
     );
   } else {
@@ -198,9 +256,14 @@ void _Thread_queue_Extract( Thread_Control *the_thread )
   }
 }
 
-Thread_Control *_Thread_queue_Dequeue(
+Thread_Control *_Thread_queue_Do_dequeue(
   Thread_queue_Control          *the_thread_queue,
   const Thread_queue_Operations *operations
+#if defined(RTEMS_MULTIPROCESSING)
+  ,
+  Thread_queue_MP_callout        mp_callout,
+  Objects_Id                     mp_id
+#endif
 )
 {
   ISR_lock_Context  lock_context;
@@ -217,6 +280,8 @@ Thread_Control *_Thread_queue_Dequeue(
       &the_thread_queue->Queue,
       operations,
       the_thread,
+      mp_callout,
+      mp_id,
       &lock_context
     );
   } else {
diff --git a/cpukit/score/src/threadqflush.c b/cpukit/score/src/threadqflush.c
index 56dd805..c508314 100644
--- a/cpukit/score/src/threadqflush.c
+++ b/cpukit/score/src/threadqflush.c
@@ -51,14 +51,11 @@ void _Thread_queue_Do_flush(
       &the_thread_queue->Queue,
       operations,
       the_thread,
+      mp_callout,
+      mp_id,
       &lock_context
     );
 
-#if defined(RTEMS_MULTIPROCESSING)
-    if ( !_Objects_Is_local_id( the_thread->Object.id ) )
-      ( *mp_callout )( the_thread, mp_id );
-#endif
-
     _Thread_queue_Acquire( the_thread_queue, &lock_context );
   }
 



More information about the vc mailing list