[PATCH] score: Delete Thread_Wait_information::id

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Apr 5 12:48:55 UTC 2016


This field was only by the monitor in non-multiprocessing
configurations.  Add new field Thread_Wait_information::remote_id in
multiprocessing configurations and use it for the remote procedure call
thread queue.

Add _Thread_Wait_get_id() to obtain the object identifier for debug and
system information tools.  Ensure the object layout via static asserts.
Add test cases to sptests/spthreadq01.
---
 cpukit/libmisc/monitor/mon-task.c                |  32 +-
 cpukit/posix/include/rtems/posix/cond.h          |   2 +-
 cpukit/posix/include/rtems/posix/mqueue.h        |   2 +-
 cpukit/posix/include/rtems/posix/mutex.h         |   2 +-
 cpukit/posix/include/rtems/posix/semaphore.h     |   2 +-
 cpukit/posix/src/condwaitsupp.c                  |   7 +-
 cpukit/posix/src/mqueuerecvsupp.c                |   6 +
 cpukit/posix/src/mutexlocksupp.c                 |   3 +
 cpukit/posix/src/pbarrierwait.c                  |   4 +-
 cpukit/posix/src/prwlockwrlock.c                 |   4 +-
 cpukit/posix/src/semaphorewaitsupp.c             |   6 +
 cpukit/rtems/include/rtems/rtems/barrier.h       |   4 +-
 cpukit/rtems/include/rtems/rtems/message.h       |   4 +-
 cpukit/rtems/include/rtems/rtems/sem.h           |  14 +-
 cpukit/rtems/src/barrierwait.c                   |   4 +-
 cpukit/rtems/src/msgqreceive.c                   |   7 +-
 cpukit/rtems/src/regiongetsegment.c              |   1 -
 cpukit/rtems/src/semobtain.c                     |  12 +-
 cpukit/score/Makefile.am                         |   1 +
 cpukit/score/include/rtems/score/coremuteximpl.h |   1 -
 cpukit/score/include/rtems/score/coresemimpl.h   |   1 -
 cpukit/score/include/rtems/score/thread.h        |   9 +-
 cpukit/score/include/rtems/score/threadimpl.h    |  36 +++
 cpukit/score/src/corebarrierwait.c               |   2 -
 cpukit/score/src/coremsgseize.c                  |   1 -
 cpukit/score/src/coremsgsubmit.c                 |   1 -
 cpukit/score/src/corerwlockobtainread.c          |   1 -
 cpukit/score/src/corerwlockobtainwrite.c         |   1 -
 cpukit/score/src/mpci.c                          |   2 +-
 cpukit/score/src/threadmp.c                      |   1 -
 cpukit/score/src/threadqextractwithproxy.c       |   2 +-
 cpukit/score/src/threadwaitgetid.c               |  54 ++++
 testsuites/sptests/spthreadq01/init.c            | 365 ++++++++++++++++++++++-
 33 files changed, 550 insertions(+), 44 deletions(-)
 create mode 100644 cpukit/score/src/threadwaitgetid.c

diff --git a/cpukit/libmisc/monitor/mon-task.c b/cpukit/libmisc/monitor/mon-task.c
index 341a403..96891e2 100644
--- a/cpukit/libmisc/monitor/mon-task.c
+++ b/cpukit/libmisc/monitor/mon-task.c
@@ -14,26 +14,46 @@
 #include <stdio.h>
 #include <string.h>    /* memcpy() */
 
+static void
+rtems_monitor_task_wait_info(
+    rtems_monitor_task_t *canonical_task,
+    Thread_Control       *rtems_thread
+)
+{
+    ISR_lock_Context  lock_context;
+    void             *lock;
+
+    lock = _Thread_Lock_acquire( rtems_thread, &lock_context );
+
+    canonical_task->state = rtems_thread->current_state;
+    canonical_task->wait_id = _Thread_Wait_get_id( rtems_thread );
+    canonical_task->wait_queue = rtems_thread->Wait.queue;
+    canonical_task->wait_operations = rtems_thread->Wait.operations;
+
+    _Thread_Lock_release( lock, &lock_context );
+}
+
 void
 rtems_monitor_task_canonical(
     rtems_monitor_task_t  *canonical_task,
     const void            *thread_void
 )
 {
-    const Thread_Control *rtems_thread = (const Thread_Control *) thread_void;
-    RTEMS_API_Control    *api;
+    Thread_Control    *rtems_thread;
+    RTEMS_API_Control *api;
+
+    rtems_thread =
+      RTEMS_DECONST( Thread_Control *, (const Thread_Control *) thread_void );
 
     api = rtems_thread->API_Extensions[ THREAD_API_RTEMS ];
 
+    rtems_monitor_task_wait_info( canonical_task, rtems_thread );
+
     canonical_task->entry = rtems_thread->Start.Entry;
     canonical_task->stack = rtems_thread->Start.Initial_stack.area;
     canonical_task->stack_size = rtems_thread->Start.Initial_stack.size;
     canonical_task->cpu = _Per_CPU_Get_index( _Thread_Get_CPU( rtems_thread ) );
     canonical_task->priority = rtems_thread->current_priority;
-    canonical_task->state = rtems_thread->current_state;
-    canonical_task->wait_id = rtems_thread->Wait.id;
-    canonical_task->wait_queue = rtems_thread->Wait.queue;
-    canonical_task->wait_operations = rtems_thread->Wait.operations;
     canonical_task->events = api->Event.pending_events;
     /*
      * FIXME: make this optionally cpu_time_executed
diff --git a/cpukit/posix/include/rtems/posix/cond.h b/cpukit/posix/include/rtems/posix/cond.h
index 00a0fdb..1839279 100644
--- a/cpukit/posix/include/rtems/posix/cond.h
+++ b/cpukit/posix/include/rtems/posix/cond.h
@@ -42,9 +42,9 @@ extern "C" {
 
 typedef struct {
    Objects_Control       Object;
+   Thread_queue_Control  Wait_queue;
    int                   process_shared;
    pthread_mutex_t       Mutex;
-   Thread_queue_Control  Wait_queue;
 }  POSIX_Condition_variables_Control;
 
 #ifdef __cplusplus
diff --git a/cpukit/posix/include/rtems/posix/mqueue.h b/cpukit/posix/include/rtems/posix/mqueue.h
index 473183d..9e74fb6 100644
--- a/cpukit/posix/include/rtems/posix/mqueue.h
+++ b/cpukit/posix/include/rtems/posix/mqueue.h
@@ -54,11 +54,11 @@ extern "C" {
 
 typedef struct {
    Objects_Control             Object;
+   CORE_message_queue_Control  Message_queue;
    int                         process_shared;
    bool                        named;
    bool                        linked;
    uint32_t                    open_count;
-   CORE_message_queue_Control  Message_queue;
    struct sigevent             notification;
 }  POSIX_Message_queue_Control;
 
diff --git a/cpukit/posix/include/rtems/posix/mutex.h b/cpukit/posix/include/rtems/posix/mutex.h
index 5243d4c..bc8e529 100644
--- a/cpukit/posix/include/rtems/posix/mutex.h
+++ b/cpukit/posix/include/rtems/posix/mutex.h
@@ -42,8 +42,8 @@ extern "C" {
 
 typedef struct {
    Objects_Control     Object;
-   int                 process_shared;
    CORE_mutex_Control  Mutex;
+   int                 process_shared;
 }  POSIX_Mutex_Control;
 
 /** @} */
diff --git a/cpukit/posix/include/rtems/posix/semaphore.h b/cpukit/posix/include/rtems/posix/semaphore.h
index 5aef39b..45de4a9 100644
--- a/cpukit/posix/include/rtems/posix/semaphore.h
+++ b/cpukit/posix/include/rtems/posix/semaphore.h
@@ -42,11 +42,11 @@ extern "C" {
 
 typedef struct {
    Objects_Control         Object;
+   CORE_semaphore_Control  Semaphore;
    int                     process_shared;
    bool                    named;
    bool                    linked;
    uint32_t                open_count;
-   CORE_semaphore_Control  Semaphore;
    /*
     *  sem_t is 32-bit.  If Object_Id is 16-bit, then they are not
     *  interchangeable.  We have to be able to return a pointer to
diff --git a/cpukit/posix/src/condwaitsupp.c b/cpukit/posix/src/condwaitsupp.c
index d4e2403..0a7e308 100644
--- a/cpukit/posix/src/condwaitsupp.c
+++ b/cpukit/posix/src/condwaitsupp.c
@@ -24,9 +24,15 @@
 #include <rtems/system.h>
 #include <rtems/score/watchdog.h>
 #include <rtems/score/statesimpl.h>
+#include <rtems/score/threadimpl.h>
 #include <rtems/posix/condimpl.h>
 #include <rtems/posix/muteximpl.h>
 
+THREAD_WAIT_QUEUE_OBJECT_ASSERT(
+  POSIX_Condition_variables_Control,
+  Wait_queue
+);
+
 int _POSIX_Condition_variables_Wait_support(
   pthread_cond_t            *cond,
   pthread_mutex_t           *mutex,
@@ -75,7 +81,6 @@ int _POSIX_Condition_variables_Wait_support(
 
         executing = _Thread_Executing;
         executing->Wait.return_code = 0;
-        executing->Wait.id          = *cond;
 
         _Thread_queue_Enqueue(
           &the_cond->Wait_queue,
diff --git a/cpukit/posix/src/mqueuerecvsupp.c b/cpukit/posix/src/mqueuerecvsupp.c
index 54d0ac1..bbbc234 100644
--- a/cpukit/posix/src/mqueuerecvsupp.c
+++ b/cpukit/posix/src/mqueuerecvsupp.c
@@ -28,9 +28,15 @@
 
 #include <rtems/system.h>
 #include <rtems/score/watchdog.h>
+#include <rtems/score/threadimpl.h>
 #include <rtems/seterr.h>
 #include <rtems/posix/mqueueimpl.h>
 
+THREAD_WAIT_QUEUE_OBJECT_ASSERT(
+  POSIX_Message_queue_Control,
+  Message_queue.Wait_queue
+);
+
 /*
  *  _POSIX_Message_queue_Receive_support
  *
diff --git a/cpukit/posix/src/mutexlocksupp.c b/cpukit/posix/src/mutexlocksupp.c
index cd95a97..0ec9b85 100644
--- a/cpukit/posix/src/mutexlocksupp.c
+++ b/cpukit/posix/src/mutexlocksupp.c
@@ -24,9 +24,12 @@
 #include <rtems/system.h>
 #include <rtems/score/coremuteximpl.h>
 #include <rtems/score/watchdog.h>
+#include <rtems/score/threadimpl.h>
 #include <rtems/posix/muteximpl.h>
 #include <rtems/posix/priorityimpl.h>
 
+THREAD_WAIT_QUEUE_OBJECT_ASSERT( POSIX_Mutex_Control, Mutex.Wait_queue );
+
 /*
  *  _POSIX_Mutex_Lock_support
  *
diff --git a/cpukit/posix/src/pbarrierwait.c b/cpukit/posix/src/pbarrierwait.c
index df4472b..560e101 100644
--- a/cpukit/posix/src/pbarrierwait.c
+++ b/cpukit/posix/src/pbarrierwait.c
@@ -22,7 +22,9 @@
 #include <errno.h>
 
 #include <rtems/posix/barrierimpl.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/threadimpl.h>
+
+THREAD_WAIT_QUEUE_OBJECT_ASSERT( POSIX_Barrier_Control, Barrier.Wait_queue );
 
 /**
  * This directive allows a thread to wait at a barrier.
diff --git a/cpukit/posix/src/prwlockwrlock.c b/cpukit/posix/src/prwlockwrlock.c
index 6777464..1905460 100644
--- a/cpukit/posix/src/prwlockwrlock.c
+++ b/cpukit/posix/src/prwlockwrlock.c
@@ -24,7 +24,9 @@
 #include <errno.h>
 
 #include <rtems/posix/rwlockimpl.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/threadimpl.h>
+
+THREAD_WAIT_QUEUE_OBJECT_ASSERT( POSIX_RWLock_Control, RWLock.Wait_queue );
 
 /*
  *  pthread_rwlock_wrlock
diff --git a/cpukit/posix/src/semaphorewaitsupp.c b/cpukit/posix/src/semaphorewaitsupp.c
index 5c055be..cf8fe63 100644
--- a/cpukit/posix/src/semaphorewaitsupp.c
+++ b/cpukit/posix/src/semaphorewaitsupp.c
@@ -27,9 +27,15 @@
 #include <limits.h>
 
 #include <rtems/system.h>
+#include <rtems/score/threadimpl.h>
 #include <rtems/posix/semaphoreimpl.h>
 #include <rtems/seterr.h>
 
+THREAD_WAIT_QUEUE_OBJECT_ASSERT(
+  POSIX_Semaphore_Control,
+  Semaphore.Wait_queue
+);
+
 int _POSIX_Semaphore_Wait_support(
   sem_t             *sem,
   bool               blocking,
diff --git a/cpukit/rtems/include/rtems/rtems/barrier.h b/cpukit/rtems/include/rtems/rtems/barrier.h
index 8c3b9d3..2eea90f 100644
--- a/cpukit/rtems/include/rtems/rtems/barrier.h
+++ b/cpukit/rtems/include/rtems/rtems/barrier.h
@@ -55,10 +55,10 @@ extern "C" {
 typedef struct {
   /** This is used to manage a barrier as an object. */
   Objects_Control          Object;
-  /** This is used to specify the attributes of a barrier. */
-  rtems_attribute          attribute_set;
   /** This is used to implement the barrier. */
   CORE_barrier_Control     Barrier;
+  /** This is used to specify the attributes of a barrier. */
+  rtems_attribute          attribute_set;
 }   Barrier_Control;
 
 /**
diff --git a/cpukit/rtems/include/rtems/rtems/message.h b/cpukit/rtems/include/rtems/rtems/message.h
index 0fad595..8ae9e15 100644
--- a/cpukit/rtems/include/rtems/rtems/message.h
+++ b/cpukit/rtems/include/rtems/rtems/message.h
@@ -53,10 +53,10 @@ extern "C" {
 typedef struct {
   /** This field is the inherited object characteristics. */
   Objects_Control             Object;
-  /** This field is the attribute set as defined by the API. */
-  rtems_attribute             attribute_set;
   /** This field is the instance of the SuperCore Message Queue. */
   CORE_message_queue_Control  message_queue;
+  /** This field is the attribute set as defined by the API. */
+  rtems_attribute             attribute_set;
 }   Message_queue_Control;
 
 /**
diff --git a/cpukit/rtems/include/rtems/rtems/sem.h b/cpukit/rtems/include/rtems/rtems/sem.h
index 6c71a9d..b3950a2 100644
--- a/cpukit/rtems/include/rtems/rtems/sem.h
+++ b/cpukit/rtems/include/rtems/rtems/sem.h
@@ -65,13 +65,6 @@ typedef struct {
   Objects_Control          Object;
 
   /**
-   *  This is the Classic API attribute provided to the create directive.
-   *  It is translated into behavioral attributes on the SuperCore Semaphore
-   *  or Mutex instance.
-   */
-  rtems_attribute          attribute_set;
-
-  /**
    *  This contains the memory associated with the SuperCore Semaphore or
    *  Mutex instance that provides the primary functionality of each
    *  Classic API Semaphore instance.  The structure used is dependent
@@ -97,6 +90,13 @@ typedef struct {
     MRSP_Control mrsp;
 #endif
   } Core_control;
+
+  /**
+   *  This is the Classic API attribute provided to the create directive.
+   *  It is translated into behavioral attributes on the SuperCore Semaphore
+   *  or Mutex instance.
+   */
+  rtems_attribute          attribute_set;
 }   Semaphore_Control;
 
 /**
diff --git a/cpukit/rtems/src/barrierwait.c b/cpukit/rtems/src/barrierwait.c
index fa7ab8e..3a30593 100644
--- a/cpukit/rtems/src/barrierwait.c
+++ b/cpukit/rtems/src/barrierwait.c
@@ -22,7 +22,9 @@
 #include <rtems/rtems/status.h>
 #include <rtems/rtems/support.h>
 #include <rtems/rtems/barrierimpl.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/threadimpl.h>
+
+THREAD_WAIT_QUEUE_OBJECT_ASSERT( Barrier_Control, Barrier.Wait_queue );
 
 rtems_status_code rtems_barrier_wait(
   rtems_id        id,
diff --git a/cpukit/rtems/src/msgqreceive.c b/cpukit/rtems/src/msgqreceive.c
index 2b9a4e7..3b4945e 100644
--- a/cpukit/rtems/src/msgqreceive.c
+++ b/cpukit/rtems/src/msgqreceive.c
@@ -22,7 +22,7 @@
 #include <rtems/score/chain.h>
 #include <rtems/score/isr.h>
 #include <rtems/score/coremsgimpl.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/threadimpl.h>
 #include <rtems/score/wkspace.h>
 #include <rtems/rtems/status.h>
 #include <rtems/rtems/attrimpl.h>
@@ -30,6 +30,11 @@
 #include <rtems/rtems/optionsimpl.h>
 #include <rtems/rtems/support.h>
 
+THREAD_WAIT_QUEUE_OBJECT_ASSERT(
+  Message_queue_Control,
+  message_queue.Wait_queue
+);
+
 rtems_status_code rtems_message_queue_receive(
   rtems_id        id,
   void           *buffer,
diff --git a/cpukit/rtems/src/regiongetsegment.c b/cpukit/rtems/src/regiongetsegment.c
index b040ebe..0d1ac57 100644
--- a/cpukit/rtems/src/regiongetsegment.c
+++ b/cpukit/rtems/src/regiongetsegment.c
@@ -75,7 +75,6 @@ rtems_status_code rtems_region_get_segment(
             _Thread_Disable_dispatch();
             _RTEMS_Unlock_allocator();
 
-            executing->Wait.id              = id;
             executing->Wait.count           = size;
             executing->Wait.return_argument = segment;
 
diff --git a/cpukit/rtems/src/semobtain.c b/cpukit/rtems/src/semobtain.c
index bda39fa..0b43af4 100644
--- a/cpukit/rtems/src/semobtain.c
+++ b/cpukit/rtems/src/semobtain.c
@@ -27,10 +27,20 @@
 #include <rtems/rtems/semimpl.h>
 #include <rtems/score/coremuteximpl.h>
 #include <rtems/score/coresemimpl.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/threadimpl.h>
 
 #include <rtems/score/interr.h>
 
+THREAD_WAIT_QUEUE_OBJECT_ASSERT(
+  Semaphore_Control,
+  Core_control.mutex.Wait_queue
+);
+
+THREAD_WAIT_QUEUE_OBJECT_ASSERT(
+  Semaphore_Control,
+  Core_control.semaphore.Wait_queue
+);
+
 rtems_status_code rtems_semaphore_obtain(
   rtems_id        id,
   rtems_option    option_set,
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 6ff4e02..5d5f688 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -308,6 +308,7 @@ libscore_a_SOURCES += src/threadentryadaptorpointer.c
 libscore_a_SOURCES += src/threadgetcputimeused.c
 libscore_a_SOURCES += src/threadglobalconstruction.c
 libscore_a_SOURCES += src/threadtimeout.c
+libscore_a_SOURCES += src/threadwaitgetid.c
 libscore_a_SOURCES += src/threadyield.c
 
 if HAS_SMP
diff --git a/cpukit/score/include/rtems/score/coremuteximpl.h b/cpukit/score/include/rtems/score/coremuteximpl.h
index b22f4a7..a1cbb17 100644
--- a/cpukit/score/include/rtems/score/coremuteximpl.h
+++ b/cpukit/score/include/rtems/score/coremuteximpl.h
@@ -265,7 +265,6 @@ RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize_body(
       executing->Wait.return_code =
         CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT;
     } else {
-      executing->Wait.id = id;
       _CORE_mutex_Seize_interrupt_blocking(
         the_mutex,
         executing,
diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h
index c70e54f..46033a8 100644
--- a/cpukit/score/include/rtems/score/coresemimpl.h
+++ b/cpukit/score/include/rtems/score/coresemimpl.h
@@ -251,7 +251,6 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize(
     return;
   }
 
-  executing->Wait.id = id;
   _Thread_queue_Enqueue_critical(
     &the_semaphore->Wait_queue.Queue,
     the_semaphore->operations,
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index ffca164..949e8ca 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -291,8 +291,13 @@ typedef struct {
     RBTree_Node RBTree;
   } Node;
 
-  /** This field is the Id of the object this thread is waiting upon. */
-  Objects_Id            id;
+#if defined(RTEMS_MULTIPROCESSING)
+  /*
+   * @brief This field is the identifier of the remote object this thread is
+   * waiting upon.
+   */
+  Objects_Id            remote_id;
+#endif
   /** This field is used to return an integer while when blocked. */
   uint32_t              count;
   /** This field is for a pointer to a user return argument. */
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 516441e..6b65e8e 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -1449,6 +1449,42 @@ RTEMS_INLINE_ROUTINE void _Thread_Wait_set_timeout_code(
 }
 
 /**
+ * @brief Helper structure to ensure that all objects containing a thread queue
+ * have the right layout.
+ *
+ * @see _Thread_Wait_get_id() and THREAD_WAIT_QUEUE_OBJECT_ASSERT().
+ */
+typedef struct {
+  Objects_Control      Object;
+  Thread_queue_Control Wait_queue;
+} Thread_Wait_queue_object;
+
+#define THREAD_WAIT_QUEUE_OBJECT_ASSERT( object_type, wait_queue_member ) \
+  RTEMS_STATIC_ASSERT( \
+    offsetof( object_type, wait_queue_member ) \
+      == offsetof( Thread_Wait_queue_object, Wait_queue ) \
+    && ( &( ( (object_type *) 0 )->wait_queue_member ) \
+      == ( &( (Thread_Wait_queue_object *) 0 )->Wait_queue ) ), \
+    object_type \
+  )
+
+/**
+ * @brief Returns the object identifier of the object containing the current
+ * thread wait queue.
+ *
+ * This function may be used for debug and system information purposes.  The
+ * caller must be the owner of the thread lock.
+ *
+ * @retval 0 The thread waits on no thread queue currently, the thread wait
+ *   queue is not contained in an object, or the current thread state provides
+ *   insufficient information, e.g. the thread is in the middle of a blocking
+ *   operation.
+ * @retval other The object identifier of the object containing the thread wait
+ *   queue.
+ */
+Objects_Id _Thread_Wait_get_id( const Thread_Control *the_thread );
+
+/**
  * @brief General purpose thread wait timeout.
  *
  * @param[in] watchdog The thread timer watchdog.
diff --git a/cpukit/score/src/corebarrierwait.c b/cpukit/score/src/corebarrierwait.c
index 4fadc03..52cbe74 100644
--- a/cpukit/score/src/corebarrierwait.c
+++ b/cpukit/score/src/corebarrierwait.c
@@ -47,8 +47,6 @@ void _CORE_barrier_Wait(
     }
   }
 
-  executing->Wait.id = id;
-
   _Thread_queue_Enqueue_critical(
     &the_barrier->Wait_queue.Queue,
     CORE_BARRIER_TQ_OPERATIONS,
diff --git a/cpukit/score/src/coremsgseize.c b/cpukit/score/src/coremsgseize.c
index 9d26fb1..34a3c50 100644
--- a/cpukit/score/src/coremsgseize.c
+++ b/cpukit/score/src/coremsgseize.c
@@ -127,7 +127,6 @@ void _CORE_message_queue_Seize(
     return;
   }
 
-  executing->Wait.id = id;
   executing->Wait.return_argument_second.mutable_object = buffer;
   executing->Wait.return_argument = size_p;
   /* Wait.count will be filled in with the message priority */
diff --git a/cpukit/score/src/coremsgsubmit.c b/cpukit/score/src/coremsgsubmit.c
index 5f61c5e..02de12f 100644
--- a/cpukit/score/src/coremsgsubmit.c
+++ b/cpukit/score/src/coremsgsubmit.c
@@ -126,7 +126,6 @@ CORE_message_queue_Status _CORE_message_queue_Submit(
      *  it as a variable.  Doing this emphasizes how dangerous it
      *  would be to use this variable prior to here.
      */
-    executing->Wait.id = id;
     executing->Wait.return_argument_second.immutable_object = buffer;
     executing->Wait.option = (uint32_t) size;
     executing->Wait.count = submit_type;
diff --git a/cpukit/score/src/corerwlockobtainread.c b/cpukit/score/src/corerwlockobtainread.c
index 97d7b9e..4676dd7 100644
--- a/cpukit/score/src/corerwlockobtainread.c
+++ b/cpukit/score/src/corerwlockobtainread.c
@@ -81,7 +81,6 @@ void _CORE_RWLock_Obtain_for_reading(
      *  We need to wait to enter this critical section
      */
 
-    executing->Wait.id          = id;
     executing->Wait.option      = CORE_RWLOCK_THREAD_WAITING_FOR_READ;
     executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
 
diff --git a/cpukit/score/src/corerwlockobtainwrite.c b/cpukit/score/src/corerwlockobtainwrite.c
index 28de842..0441650 100644
--- a/cpukit/score/src/corerwlockobtainwrite.c
+++ b/cpukit/score/src/corerwlockobtainwrite.c
@@ -68,7 +68,6 @@ void _CORE_RWLock_Obtain_for_writing(
      *  We need to wait to enter this critical section
      */
 
-    executing->Wait.id          = id;
     executing->Wait.option      = CORE_RWLOCK_THREAD_WAITING_FOR_WRITE;
     executing->Wait.return_code = CORE_RWLOCK_SUCCESSFUL;
 
diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c
index 76ca4c8..20d5084 100644
--- a/cpukit/score/src/mpci.c
+++ b/cpukit/score/src/mpci.c
@@ -242,7 +242,7 @@ uint32_t   _MPCI_Send_request_packet (
     the_packet->to_convert =
        ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) / sizeof(uint32_t);
 
-    executing->Wait.id = the_packet->id;
+    executing->Wait.remote_id = the_packet->id;
 
     (*_MPCI_table->send_packet)( destination, the_packet );
 
diff --git a/cpukit/score/src/threadmp.c b/cpukit/score/src/threadmp.c
index 2d7e924..33c9078 100644
--- a/cpukit/score/src/threadmp.c
+++ b/cpukit/score/src/threadmp.c
@@ -95,7 +95,6 @@ Thread_Control *_Thread_MP_Allocate_proxy (
 
     the_proxy->current_state = _States_Set( STATES_DORMANT, the_state );
 
-    the_proxy->Wait.id                      = executing->Wait.id;
     the_proxy->Wait.count                   = executing->Wait.count;
     the_proxy->Wait.return_argument         = executing->Wait.return_argument;
     the_proxy->Wait.return_argument_second  = executing->Wait.return_argument_second;
diff --git a/cpukit/score/src/threadqextractwithproxy.c b/cpukit/score/src/threadqextractwithproxy.c
index 9bbf9c6..efe0940 100644
--- a/cpukit/score/src/threadqextractwithproxy.c
+++ b/cpukit/score/src/threadqextractwithproxy.c
@@ -41,7 +41,7 @@ void _Thread_queue_Extract_with_proxy(
       Objects_Information                  *the_information;
       Objects_Thread_queue_Extract_callout  proxy_extract_callout;
 
-      id = the_thread->Wait.id;
+      id = the_thread->Wait.remote_id;
       the_information = _Objects_Get_information_id( id );
       proxy_extract_callout = the_information->extract;
 
diff --git a/cpukit/score/src/threadwaitgetid.c b/cpukit/score/src/threadwaitgetid.c
new file mode 100644
index 0000000..0851e8f
--- /dev/null
+++ b/cpukit/score/src/threadwaitgetid.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/score/threadimpl.h>
+
+#define THREAD_WAIT_QUEUE_OBJECT_STATES \
+  ( STATES_WAITING_FOR_BARRIER \
+    | STATES_WAITING_FOR_CONDITION_VARIABLE \
+    | STATES_WAITING_FOR_MESSAGE \
+    | STATES_WAITING_FOR_MUTEX \
+    | STATES_WAITING_FOR_RWLOCK \
+    | STATES_WAITING_FOR_SEMAPHORE )
+
+Objects_Id _Thread_Wait_get_id( const Thread_Control *the_thread )
+{
+  States_Control current_state;
+
+  current_state = the_thread->current_state;
+
+#if defined(RTEMS_MULTIPROCESSING)
+  if ( ( current_state & STATES_WAITING_FOR_RPC_REPLY ) != 0 ) {
+    return the_thread->Wait.remote_id;
+  }
+#endif
+
+  if ( ( current_state & THREAD_WAIT_QUEUE_OBJECT_STATES ) != 0 ) {
+    const Thread_Wait_queue_object *queue_object;
+
+    queue_object = RTEMS_CONTAINER_OF(
+      the_thread->Wait.queue,
+      Thread_Wait_queue_object,
+      Wait_queue.Queue
+    );
+
+    return queue_object->Object.id;
+  }
+
+  return 0;
+}
diff --git a/testsuites/sptests/spthreadq01/init.c b/testsuites/sptests/spthreadq01/init.c
index 6eef0c7..9bf15e8 100644
--- a/testsuites/sptests/spthreadq01/init.c
+++ b/testsuites/sptests/spthreadq01/init.c
@@ -13,17 +13,354 @@
 
 #include <tmacros.h>
 
-#include <sys/types.h>
-#include <rtems/score/threadqimpl.h>
+#include <rtems.h>
+
+#include <rtems/score/threadimpl.h>
+
+#if defined(RTEMS_POSIX_API)
+  #include <fcntl.h>
+  #include <mqueue.h>
+  #include <semaphore.h>
+  #include <string.h>
+  #include <pthread.h>
+
+  #include <rtems/posix/mqueueimpl.h>
+#endif
 
 const char rtems_test_name[] = "SPTHREADQ 1";
 
 static Thread_queue_Control queue = THREAD_QUEUE_INITIALIZER( "Queue" );
 
+typedef struct {
+  Thread_Control *master;
+  rtems_id master_id;
+  rtems_id worker_id;
+  rtems_id sem;
+  rtems_id mtx;
+  rtems_id mq;
+  rtems_id br;
+#if defined(RTEMS_POSIX_API)
+  sem_t psem;
+  pthread_mutex_t pmtx;
+  pthread_cond_t pcv;
+  pthread_rwlock_t prw;
+  mqd_t pmq;
+#endif
+} test_context;
+
+static test_context test_instance;
+
+static void wait_for_worker(test_context *ctx)
+{
+  rtems_status_code sc;
+
+  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void wake_up_master(test_context *ctx)
+{
+  rtems_status_code sc;
+
+  sc = rtems_event_transient_send(ctx->master_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static rtems_id get_wait_id(test_context *ctx)
+{
+  ISR_lock_Context lock_context;
+  void *lock;
+  rtems_id id;
+
+  lock = _Thread_Lock_acquire(ctx->master, &lock_context);
+  id = _Thread_Wait_get_id(ctx->master);
+  _Thread_Lock_release(lock, &lock_context);
+
+  return id;
+}
+
+static void classic_worker(test_context *ctx)
+{
+  rtems_status_code sc;
+  char buf[1];
+
+  wake_up_master(ctx);
+  rtems_test_assert(get_wait_id(ctx) == ctx->sem);
+
+  sc = rtems_semaphore_release(ctx->sem);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  wake_up_master(ctx);
+  rtems_test_assert(get_wait_id(ctx) == ctx->mtx);
+
+  sc = rtems_semaphore_release(ctx->mtx);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  wake_up_master(ctx);
+  rtems_test_assert(get_wait_id(ctx) == ctx->mq);
+
+  buf[0] = 'X';
+  sc = rtems_message_queue_send(ctx->mq, &buf[0], sizeof(buf));
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  wake_up_master(ctx);
+  rtems_test_assert(get_wait_id(ctx) == ctx->br);
+
+  sc = rtems_barrier_wait(ctx->br, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void posix_worker(test_context *ctx)
+{
+#if defined(RTEMS_POSIX_API)
+  int rv;
+  int eno;
+  char buf[1];
+  POSIX_Message_queue_Control_fd *the_mq_fd;
+  Objects_Locations location;
+  ISR_lock_Context lock_context;
+
+  wake_up_master(ctx);
+  rtems_test_assert(get_wait_id(ctx) == ctx->psem);
+
+  rv = sem_post(&ctx->psem);
+  rtems_test_assert(rv == 0);
+
+  eno = pthread_mutex_lock(&ctx->pmtx);
+  rtems_test_assert(eno == 0);
+
+  wake_up_master(ctx);
+  rtems_test_assert(get_wait_id(ctx) == ctx->pmtx);
+
+  eno = pthread_mutex_unlock(&ctx->pmtx);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutex_lock(&ctx->pmtx);
+  rtems_test_assert(eno == 0);
+
+  rtems_test_assert(get_wait_id(ctx) == ctx->pcv);
+
+  eno = pthread_cond_signal(&ctx->pcv);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutex_unlock(&ctx->pmtx);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_rwlock_wrlock(&ctx->prw);
+  rtems_test_assert(eno == 0);
+
+  wake_up_master(ctx);
+  rtems_test_assert(get_wait_id(ctx) == ctx->prw);
+
+  eno = pthread_rwlock_unlock(&ctx->prw);
+  rtems_test_assert(eno == 0);
+
+  wake_up_master(ctx);
+  the_mq_fd = _POSIX_Message_queue_Get_fd_interrupt_disable(
+    ctx->pmq,
+    &location,
+    &lock_context
+  );
+  _ISR_lock_ISR_enable(&lock_context);
+  rtems_test_assert(the_mq_fd != NULL);
+  rtems_test_assert(location == OBJECTS_LOCAL);
+  rtems_test_assert(get_wait_id(ctx) == the_mq_fd->Queue->Object.id);
+
+  buf[0] = 'x';
+  rv = mq_send(ctx->pmq, &buf[0], sizeof(buf), 0);
+  rtems_test_assert(rv == 0);
+#endif
+}
+
+static rtems_task worker(rtems_task_argument arg)
+{
+  test_context *ctx = (test_context *) arg;
+
+  rtems_test_assert(get_wait_id(ctx) == 0);
+
+  classic_worker(ctx);
+  posix_worker(ctx);
+}
+
+static void test_classic_init(test_context *ctx)
+{
+  rtems_status_code sc;
+
+  sc = rtems_semaphore_create(
+    rtems_build_name('S', 'E', 'M', ' '),
+    0,
+    RTEMS_COUNTING_SEMAPHORE,
+    0,
+    &ctx->sem
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_semaphore_create(
+    rtems_build_name('M', 'T', 'X', ' '),
+    1,
+    RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
+    0,
+    &ctx->mtx
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_message_queue_create(
+    rtems_build_name('M', 'Q', ' ', ' '),
+    1,
+    1,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &ctx->mq
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_barrier_create(
+    rtems_build_name('B', 'R', ' ', ' '),
+    RTEMS_BARRIER_AUTOMATIC_RELEASE,
+    2,
+    &ctx->br
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_posix_init(test_context *ctx)
+{
+#if defined(RTEMS_POSIX_API)
+  int rv;
+  int eno;
+  struct mq_attr attr;
+
+  rv = sem_init(&ctx->psem, 0, 0);
+  rtems_test_assert(rv == 0);
+
+  eno = pthread_mutex_init(&ctx->pmtx, NULL);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_cond_init(&ctx->pcv, NULL);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_rwlock_init(&ctx->prw, NULL);
+  rtems_test_assert(eno == 0);
+
+  memset(&attr, 0, sizeof(attr));
+  attr.mq_maxmsg = 1;
+  attr.mq_msgsize = sizeof(char);
+
+  ctx->pmq = mq_open("mq", O_CREAT | O_RDWR, 0x777, &attr);
+  rtems_test_assert(ctx->mq != -1);
+#endif
+}
+
+static void test_context_init(test_context *ctx)
+{
+  rtems_status_code sc;
+
+  ctx->master = _Thread_Get_executing();
+  ctx->master_id = rtems_task_self();
+
+  test_classic_init(ctx);
+  test_posix_init(ctx);
+
+  sc = rtems_task_create(
+    rtems_build_name('W', 'O', 'R', 'K'),
+    2,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &ctx->worker_id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(ctx->worker_id, worker, (rtems_task_argument) ctx);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_classic_obj(test_context *ctx)
+{
+  rtems_status_code sc;
+  char buf[1];
+  size_t n;
+
+  wait_for_worker(ctx);
+
+  sc = rtems_semaphore_obtain(ctx->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  wait_for_worker(ctx);
+
+  sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  wait_for_worker(ctx);
+
+  buf[0] = 'Y';
+  n = 123;
+  sc = rtems_message_queue_receive(
+    ctx->mq,
+    &buf[0],
+    &n,
+    RTEMS_WAIT,
+    RTEMS_NO_TIMEOUT
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+  rtems_test_assert(buf[0] == 'X');
+  rtems_test_assert(n == sizeof(buf));
+
+  wait_for_worker(ctx);
+
+  sc = rtems_barrier_wait(ctx->br, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_posix_obj(test_context *ctx)
+{
+#if defined(RTEMS_POSIX_API)
+  int rv;
+  int eno;
+  char buf[1];
+  unsigned prio;
+  ssize_t n;
+
+  wait_for_worker(ctx);
+
+  rv = sem_wait(&ctx->psem);
+  rtems_test_assert(rv == 0);
+
+  wait_for_worker(ctx);
+
+  eno = pthread_mutex_lock(&ctx->pmtx);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_cond_wait(&ctx->pcv, &ctx->pmtx);
+  rtems_test_assert(eno == 0);
+
+  eno = pthread_mutex_unlock(&ctx->pmtx);
+  rtems_test_assert(eno == 0);
+
+  wait_for_worker(ctx);
+
+  eno = pthread_rwlock_wrlock(&ctx->prw);
+  rtems_test_assert(eno == 0);
+
+  wait_for_worker(ctx);
+
+  buf[0] = 'y';
+  prio = 1;
+  n = mq_receive(ctx->pmq, &buf[0], sizeof(buf), &prio);
+  rtems_test_assert(n == (ssize_t) sizeof(buf));
+  rtems_test_assert(buf[0] == 'x');
+  rtems_test_assert(prio == 0);
+#endif
+}
+
 static rtems_task Init(
   rtems_task_argument ignored
 )
 {
+  test_context *ctx = &test_instance;
+
   TEST_BEGIN();
 
   puts( "Init - _Thread_queue_Extract - thread not blocked on a thread queue" );
@@ -32,6 +369,10 @@ static rtems_task Init(
   _Thread_Enable_dispatch();
   /* is there more to check? */
 
+  test_context_init(ctx);
+  test_classic_obj(ctx);
+  test_posix_obj(ctx);
+
   rtems_test_assert( queue.Queue.heads == NULL );
 
   TEST_END();
@@ -43,7 +384,25 @@ static rtems_task Init(
 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
 #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
 
-#define CONFIGURE_MAXIMUM_TASKS  1
+#define CONFIGURE_MAXIMUM_TASKS  2
+#define CONFIGURE_MAXIMUM_SEMAPHORES  2
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES  1
+#define CONFIGURE_MAXIMUM_BARRIERS  1
+
+#if defined(RTEMS_POSIX_API)
+  #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1
+  #define CONFIGURE_MAXIMUM_POSIX_MUTEXES 1
+  #define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 1
+  #define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
+  #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 1
+  #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS 1
+  #define CONFIGURE_MESSAGE_BUFFER_MEMORY \
+    (2 * CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(1, 1))
+#else
+  #define CONFIGURE_MESSAGE_BUFFER_MEMORY \
+    CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(1, 1)
+#endif
+
 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
 
 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
-- 
1.8.4.5



More information about the devel mailing list