forked from Imagelibrary/rtems
posix: Simplify key implementation
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() */
|
||||
|
||||
Reference in New Issue
Block a user