[PATCH 5/5] score: Rework MP thread queue callout support

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Apr 1 13:56:15 UTC 2016


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                  | 111 ++++++--
 cpukit/score/src/threadqflush.c                    |   7 +-
 37 files changed, 793 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 df4472b..890371b 100644
--- a/cpukit/posix/src/pbarrierwait.c
+++ b/cpukit/posix/src/pbarrierwait.c
@@ -53,10 +53,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 fa7ab8e..9e92ceb 100644
--- a/cpukit/rtems/src/barrierwait.c
+++ b/cpukit/rtems/src/barrierwait.c
@@ -41,10 +41,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 68187c9..b94f03b 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.
@@ -303,28 +292,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 96619e6..4e5c6a1 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 ffca164..b835221 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -413,8 +413,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;
 
@@ -426,6 +437,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 4fadc03..6d38a94 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 9d26fb1..bca63df 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
@@ -141,7 +140,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 5f61c5e..e543a70 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;
   }
 
@@ -140,10 +134,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 2d7e924..f803671 100644
--- a/cpukit/score/src/threadmp.c
+++ b/cpukit/score/src/threadmp.c
@@ -103,6 +103,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..2902ff0 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,54 @@ 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;
+
+    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 +161,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 +178,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 +197,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 +245,8 @@ void _Thread_queue_Extract( Thread_Control *the_thread )
       queue,
       the_thread->Wait.operations,
       the_thread,
+      NULL,
+      0,
       &lock_context
     );
   } else {
@@ -198,9 +254,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 +278,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 );
   }
 
-- 
1.8.4.5




More information about the devel mailing list