[PATCH 3/3] posix: Simplify key implementation

Sebastian Huber sebastian.huber at embedded-brains.de
Sun Aug 3 12:45:06 UTC 2014


---
 cpukit/posix/include/rtems/posix/key.h     | 33 ++++++++++++++++++++++--------
 cpukit/posix/include/rtems/posix/keyimpl.h |  4 ++--
 cpukit/posix/src/key.c                     | 20 ++++++++++--------
 cpukit/posix/src/keygetspecific.c          |  2 +-
 cpukit/posix/src/keysetspecific.c          |  6 ++++--
 5 files changed, 44 insertions(+), 21 deletions(-)

diff --git a/cpukit/posix/include/rtems/posix/key.h b/cpukit/posix/include/rtems/posix/key.h
index bfa05b1..7cc179c 100644
--- a/cpukit/posix/include/rtems/posix/key.h
+++ b/cpukit/posix/include/rtems/posix/key.h
@@ -25,6 +25,7 @@
 #include <rtems/score/chain.h>
 #include <rtems/score/object.h>
 #include <rtems/score/rbtree.h>
+#include <rtems/score/thread.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -39,20 +40,36 @@ extern "C" {
 /**@{**/
 
 /**
- * @brief The rbtree node used to manage a POSIX key and value.
+ * @brief Represents POSIX key and value pair.
  */
 typedef struct {
-  /** This field is the chain node structure. */
+  /**
+   * @brief The chain node for the per-thread value chain.
+   */
   Chain_Node Key_values_per_thread_node;
-  /** This field is the rbtree node structure. */
+
+  /**
+   * @brief The tree node for the lookup tree.
+   */
   RBTree_Node Key_value_lookup_node;
-  /** This field is the POSIX key used as an rbtree key */
+
+  /**
+   * @brief The POSIX key identifier used in combination with the thread
+   * pointer as the tree key.
+   */
   pthread_key_t key;
-  /** This field is the Thread id also used as an rbtree key */
-  Objects_Id thread_id;
-  /** This field points to the POSIX key value of specific thread */
+
+  /**
+   * @brief The thread pointer used in combination with the POSIX key
+   * identifier as the tree key.
+   */
+  Thread_Control *thread;
+
+  /**
+   * @brief The thread specific POSIX key value.
+   */
   const void *value;
-}  POSIX_Keys_Key_value_pair;
+} POSIX_Keys_Key_value_pair;
 
 /**
  * @brief The data structure used to manage a POSIX key.
diff --git a/cpukit/posix/include/rtems/posix/keyimpl.h b/cpukit/posix/include/rtems/posix/keyimpl.h
index ded030d..42989b0 100644
--- a/cpukit/posix/include/rtems/posix/keyimpl.h
+++ b/cpukit/posix/include/rtems/posix/keyimpl.h
@@ -170,12 +170,12 @@ RTEMS_INLINE_ROUTINE void _POSIX_Keys_Key_value_pair_free(
 
 RTEMS_INLINE_ROUTINE RBTree_Node *_POSIX_Keys_Find(
   pthread_key_t              key,
-  Objects_Id                 thread_id,
+  Thread_Control            *thread,
   POSIX_Keys_Key_value_pair *search_node
 )
 {
   search_node->key = key;
-  search_node->thread_id = thread_id;
+  search_node->thread = thread;
 
   return _RBTree_Find(
     &_POSIX_Keys_Key_value_lookup_tree,
diff --git a/cpukit/posix/src/key.c b/cpukit/posix/src/key.c
index 67c6e27..6753d57 100644
--- a/cpukit/posix/src/key.c
+++ b/cpukit/posix/src/key.c
@@ -51,7 +51,8 @@ RBTree_Compare_result _POSIX_Keys_Key_value_compare(
 {
   POSIX_Keys_Key_value_pair *n1;
   POSIX_Keys_Key_value_pair *n2;
-  Objects_Id thread_id1, thread_id2;
+  Thread_Control *thread1;
+  Thread_Control *thread2;
   RBTree_Compare_result diff;
 
   n1 = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node1 );
@@ -61,15 +62,18 @@ RBTree_Compare_result _POSIX_Keys_Key_value_compare(
   if ( diff )
     return diff;
 
-  thread_id1 = n1->thread_id;
-  thread_id2 = n2->thread_id;
+  thread1 = n1->thread;
+  thread2 = n2->thread;
 
-  /**
-   * if thread_id1 or thread_id2 equals to 0, only key1 and key2 is valued.
-   * it enables us search node only by pthread_key_t type key.
+  /*
+   * If thread1 or thread2 equals to NULL, only key1 and key2 is valued.  It
+   * enables us search node only by pthread_key_t type key.  Exploit that the
+   * thread control alignment is at least two to avoid integer overflows.
    */
-  if ( thread_id1 && thread_id2 )
-    return thread_id1 - thread_id2;
+  if ( thread1 != NULL && thread2 != NULL )
+    return (RBTree_Compare_result) ( (uintptr_t) thread1 >> 1 )
+      - (RBTree_Compare_result) ( (uintptr_t) thread2 >> 1 );
+
   return 0;
 }
 
diff --git a/cpukit/posix/src/keygetspecific.c b/cpukit/posix/src/keygetspecific.c
index f7e7b71..5ab37a7 100644
--- a/cpukit/posix/src/keygetspecific.c
+++ b/cpukit/posix/src/keygetspecific.c
@@ -49,7 +49,7 @@ void *pthread_getspecific(
   switch ( location ) {
 
     case OBJECTS_LOCAL:
-      p = _POSIX_Keys_Find( key, _Thread_Executing->Object.id, &search_node );
+      p = _POSIX_Keys_Find( key, _Thread_Executing, &search_node );
       if ( p != NULL ) {
         value_pair_p = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( p );
         key_data = value_pair_p->value;
diff --git a/cpukit/posix/src/keysetspecific.c b/cpukit/posix/src/keysetspecific.c
index ec17d47..ee85ac2 100644
--- a/cpukit/posix/src/keysetspecific.c
+++ b/cpukit/posix/src/keysetspecific.c
@@ -39,12 +39,14 @@ int pthread_setspecific(
   POSIX_Keys_Key_value_pair   *value_pair_ptr;
   RBTree_Node                 *p;
   POSIX_Keys_Key_value_pair    search_node;
+  Thread_Control              *executing;
 
   the_key = _POSIX_Keys_Get( key, &location );
   switch ( location ) {
 
     case OBJECTS_LOCAL:
-      p = _POSIX_Keys_Find( key, _Thread_Executing->Object.id, &search_node );
+      executing = _Thread_Executing;
+      p = _POSIX_Keys_Find( key, executing, &search_node );
       if ( p != NULL ) {
         value_pair_ptr = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( p );
         value_pair_ptr->value = value;
@@ -58,7 +60,7 @@ int pthread_setspecific(
         }
 
         value_pair_ptr->key = key;
-        value_pair_ptr->thread_id = _Thread_Executing->Object.id;
+        value_pair_ptr->thread = executing;
         value_pair_ptr->value = value;
         /* The insert can only go wrong if the same node is already in a unique
          * tree. This has been already checked with the _RBTree_Find() */
-- 
1.8.1.4




More information about the devel mailing list