From 390cfcda71c5bb0d53493210bcf4a15ee29c0498 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Sat, 2 Aug 2014 15:49:26 +0200 Subject: posix: Simplify key implementation --- 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 bfa05b1d10..7cc179c3cc 100644 --- a/cpukit/posix/include/rtems/posix/key.h +++ b/cpukit/posix/include/rtems/posix/key.h @@ -25,6 +25,7 @@ #include #include #include +#include #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() */ -- cgit v1.2.3