summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-08-02 15:49:26 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-08-05 09:30:37 +0200
commit390cfcda71c5bb0d53493210bcf4a15ee29c0498 (patch)
tree52d5af466eef00d0fd8f441f130aeb05131a21c5
parentrbtree: Add and use RBTree_Compare_result (diff)
downloadrtems-390cfcda71c5bb0d53493210bcf4a15ee29c0498.tar.bz2
posix: Simplify key implementation
-rw-r--r--cpukit/posix/include/rtems/posix/key.h33
-rw-r--r--cpukit/posix/include/rtems/posix/keyimpl.h4
-rw-r--r--cpukit/posix/src/key.c20
-rw-r--r--cpukit/posix/src/keygetspecific.c2
-rw-r--r--cpukit/posix/src/keysetspecific.c6
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 bfa05b1d10..7cc179c3cc 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 ded030d3a3..42989b0c16 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 67c6e27bc5..6753d57437 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 f7e7b71a2c..5ab37a7553 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 ec17d47b8a..ee85ac2cb5 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() */