mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-22 17:58:27 +08:00
rbtree: Add and use RBTree_Compare_result
This commit is contained in:
@@ -64,7 +64,7 @@ void _POSIX_Key_Manager_initialization(void);
|
||||
*
|
||||
* This routine compares the rbtree node
|
||||
*/
|
||||
int _POSIX_Keys_Key_value_compare(
|
||||
RBTree_Compare_result _POSIX_Keys_Key_value_compare(
|
||||
const RBTree_Node *node1,
|
||||
const RBTree_Node *node2
|
||||
);
|
||||
|
||||
@@ -44,7 +44,7 @@ RBTREE_DEFINE_EMPTY( _POSIX_Keys_Key_value_lookup_tree );
|
||||
* impossible
|
||||
*/
|
||||
|
||||
int _POSIX_Keys_Key_value_compare(
|
||||
RBTree_Compare_result _POSIX_Keys_Key_value_compare(
|
||||
const RBTree_Node *node1,
|
||||
const RBTree_Node *node2
|
||||
)
|
||||
@@ -52,7 +52,7 @@ int _POSIX_Keys_Key_value_compare(
|
||||
POSIX_Keys_Key_value_pair *n1;
|
||||
POSIX_Keys_Key_value_pair *n2;
|
||||
Objects_Id thread_id1, thread_id2;
|
||||
int diff;
|
||||
RBTree_Compare_result diff;
|
||||
|
||||
n1 = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node1 );
|
||||
n2 = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node2 );
|
||||
|
||||
@@ -154,7 +154,6 @@ struct rtems_rbheap_control {
|
||||
* @param[in] handler_arg The handler argument.
|
||||
*
|
||||
* @retval RTEMS_SUCCESSFUL Successful operation.
|
||||
* @retval RTEMS_INVALID_NUMBER The alignment is not positive.
|
||||
* @retval RTEMS_INVALID_ADDRESS The memory area is invalid.
|
||||
* @retval RTEMS_NO_MEMORY Not enough chunk descriptors.
|
||||
*/
|
||||
|
||||
@@ -55,9 +55,12 @@ typedef RBTree_Node rtems_rbtree_node;
|
||||
typedef RBTree_Control rtems_rbtree_control;
|
||||
|
||||
/**
|
||||
* This type defines function pointers for user-provided comparison
|
||||
* function. The function compares two nodes in order to determine
|
||||
* the order in a red-black tree.
|
||||
* @copydoc RBTree_Compare_result
|
||||
*/
|
||||
typedef RBTree_Compare_result rtems_rbtree_compare_result;
|
||||
|
||||
/**
|
||||
* @copydoc RBTree_Compare
|
||||
*/
|
||||
typedef RBTree_Compare rtems_rbtree_compare;
|
||||
|
||||
|
||||
+36
-28
@@ -46,12 +46,16 @@ static uintptr_t align_down(uintptr_t alignment, uintptr_t value)
|
||||
return value - excess;
|
||||
}
|
||||
|
||||
static int chunk_compare(const rtems_rbtree_node *a, const rtems_rbtree_node *b)
|
||||
static rtems_rbtree_compare_result chunk_compare(
|
||||
const rtems_rbtree_node *a,
|
||||
const rtems_rbtree_node *b
|
||||
)
|
||||
{
|
||||
const rtems_rbheap_chunk *left = rtems_rbheap_chunk_of_node(a);
|
||||
const rtems_rbheap_chunk *right = rtems_rbheap_chunk_of_node(b);
|
||||
|
||||
return (int) (left->begin - right->begin);
|
||||
return (rtems_rbtree_compare_result)
|
||||
((left->begin >> 1) - (right->begin >> 1));
|
||||
}
|
||||
|
||||
static rtems_rbheap_chunk *get_chunk(rtems_rbheap_control *control)
|
||||
@@ -93,39 +97,43 @@ rtems_status_code rtems_rbheap_initialize(
|
||||
)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
uintptr_t begin = (uintptr_t) area_begin;
|
||||
uintptr_t end = begin + area_size;
|
||||
uintptr_t aligned_begin;
|
||||
uintptr_t aligned_end;
|
||||
|
||||
if (alignment > 0) {
|
||||
uintptr_t begin = (uintptr_t) area_begin;
|
||||
uintptr_t end = begin + area_size;
|
||||
uintptr_t aligned_begin = align_up(alignment, begin);
|
||||
uintptr_t aligned_end = align_down(alignment, end);
|
||||
/*
|
||||
* Ensure that the alignment is at least two, so that we can keep
|
||||
* chunk_compare() that simple.
|
||||
*/
|
||||
alignment = alignment < 2 ? 2 : alignment;
|
||||
|
||||
if (begin < end && begin <= aligned_begin && aligned_begin < aligned_end) {
|
||||
rtems_chain_control *free_chain = &control->free_chunk_chain;
|
||||
rtems_rbtree_control *chunk_tree = &control->chunk_tree;
|
||||
rtems_rbheap_chunk *first = NULL;
|
||||
aligned_begin = align_up(alignment, begin);
|
||||
aligned_end = align_down(alignment, end);
|
||||
|
||||
rtems_chain_initialize_empty(free_chain);
|
||||
rtems_chain_initialize_empty(&control->spare_descriptor_chain);
|
||||
rtems_rbtree_initialize_empty(chunk_tree);
|
||||
control->alignment = alignment;
|
||||
control->handler_arg = handler_arg;
|
||||
control->extend_descriptors = extend_descriptors;
|
||||
if (begin < end && begin <= aligned_begin && aligned_begin < aligned_end) {
|
||||
rtems_chain_control *free_chain = &control->free_chunk_chain;
|
||||
rtems_rbtree_control *chunk_tree = &control->chunk_tree;
|
||||
rtems_rbheap_chunk *first = NULL;
|
||||
|
||||
first = get_chunk(control);
|
||||
if (first != NULL) {
|
||||
first->begin = aligned_begin;
|
||||
first->size = aligned_end - aligned_begin;
|
||||
add_to_chain(free_chain, first);
|
||||
insert_into_tree(chunk_tree, first);
|
||||
} else {
|
||||
sc = RTEMS_NO_MEMORY;
|
||||
}
|
||||
rtems_chain_initialize_empty(free_chain);
|
||||
rtems_chain_initialize_empty(&control->spare_descriptor_chain);
|
||||
rtems_rbtree_initialize_empty(chunk_tree);
|
||||
control->alignment = alignment;
|
||||
control->handler_arg = handler_arg;
|
||||
control->extend_descriptors = extend_descriptors;
|
||||
|
||||
first = get_chunk(control);
|
||||
if (first != NULL) {
|
||||
first->begin = aligned_begin;
|
||||
first->size = aligned_end - aligned_begin;
|
||||
add_to_chain(free_chain, first);
|
||||
insert_into_tree(chunk_tree, first);
|
||||
} else {
|
||||
sc = RTEMS_INVALID_ADDRESS;
|
||||
sc = RTEMS_NO_MEMORY;
|
||||
}
|
||||
} else {
|
||||
sc = RTEMS_INVALID_NUMBER;
|
||||
sc = RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
return sc;
|
||||
|
||||
@@ -89,6 +89,15 @@ typedef enum {
|
||||
RBT_RIGHT=1
|
||||
} RBTree_Direction;
|
||||
|
||||
/**
|
||||
* @brief Integer type for compare results.
|
||||
*
|
||||
* The type is large enough to represent pointers and 32-bit signed integers.
|
||||
*
|
||||
* @see RBTree_Compare.
|
||||
*/
|
||||
typedef long RBTree_Compare_result;
|
||||
|
||||
/**
|
||||
* @brief Compares two red-black tree nodes.
|
||||
*
|
||||
@@ -102,7 +111,7 @@ typedef enum {
|
||||
* @retval negative The key value of the first node is less than the one of the
|
||||
* second node.
|
||||
*/
|
||||
typedef int ( *RBTree_Compare )(
|
||||
typedef RBTree_Compare_result ( *RBTree_Compare )(
|
||||
const RBTree_Node *first,
|
||||
const RBTree_Node *second
|
||||
);
|
||||
|
||||
@@ -144,20 +144,22 @@ RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Parent_sibling(
|
||||
return _RBTree_Sibling(the_node->parent);
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _RBTree_Is_equal( int compare_result )
|
||||
RTEMS_INLINE_ROUTINE bool _RBTree_Is_equal(
|
||||
RBTree_Compare_result compare_result
|
||||
)
|
||||
{
|
||||
return compare_result == 0;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _RBTree_Is_greater(
|
||||
int compare_result
|
||||
RBTree_Compare_result compare_result
|
||||
)
|
||||
{
|
||||
return compare_result > 0;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _RBTree_Is_lesser(
|
||||
int compare_result
|
||||
RBTree_Compare_result compare_result
|
||||
)
|
||||
{
|
||||
return compare_result < 0;
|
||||
|
||||
@@ -44,7 +44,7 @@ RTEMS_INLINE_ROUTINE Scheduler_EDF_Node *_Scheduler_EDF_Thread_get_node(
|
||||
return (Scheduler_EDF_Node *) _Scheduler_Thread_get_node( the_thread );
|
||||
}
|
||||
|
||||
int _Scheduler_EDF_Compare(
|
||||
RBTree_Compare_result _Scheduler_EDF_Compare(
|
||||
const RBTree_Node* n1,
|
||||
const RBTree_Node* n2
|
||||
);
|
||||
|
||||
@@ -260,7 +260,7 @@ void _Thread_queue_Process_timeout(
|
||||
* @retval 0 The @left node is of equal importance with @right node.
|
||||
* @retval 1 The @left node is less important than @right node.
|
||||
*/
|
||||
int _Thread_queue_Compare_priority(
|
||||
RBTree_Compare_result _Thread_queue_Compare_priority(
|
||||
const RBTree_Node *left,
|
||||
const RBTree_Node *right
|
||||
);
|
||||
|
||||
@@ -30,8 +30,8 @@ RBTree_Node *_RBTree_Find(
|
||||
RBTree_Node *found = NULL;
|
||||
|
||||
while ( iter_node != NULL ) {
|
||||
int compare_result = ( *compare )( the_node, iter_node );
|
||||
RBTree_Direction dir;
|
||||
RBTree_Compare_result compare_result = ( *compare )( the_node, iter_node );
|
||||
RBTree_Direction dir;
|
||||
|
||||
if ( _RBTree_Is_equal( compare_result ) ) {
|
||||
found = iter_node;
|
||||
|
||||
@@ -12,6 +12,16 @@
|
||||
|
||||
#include <rtems/score/rbtreeimpl.h>
|
||||
|
||||
RTEMS_STATIC_ASSERT(
|
||||
sizeof( RBTree_Compare_result ) >= sizeof( intptr_t ),
|
||||
RBTree_Compare_result_intptr_t
|
||||
);
|
||||
|
||||
RTEMS_STATIC_ASSERT(
|
||||
sizeof( RBTree_Compare_result ) >= sizeof( int32_t ),
|
||||
RBTree_Compare_result_int32_t
|
||||
);
|
||||
|
||||
/** @brief Validate and fix-up tree properties for a new insert/colored node
|
||||
*
|
||||
* This routine checks and fixes the Red-Black Tree properties based on
|
||||
@@ -77,7 +87,8 @@ RBTree_Node *_RBTree_Insert(
|
||||
} else {
|
||||
/* typical binary search tree insert, descend tree to leaf and insert */
|
||||
while ( iter_node ) {
|
||||
int compare_result = ( *compare )( the_node, iter_node );
|
||||
RBTree_Compare_result compare_result =
|
||||
( *compare )( the_node, iter_node );
|
||||
|
||||
if ( is_unique && _RBTree_Is_equal( compare_result ) )
|
||||
return iter_node;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <rtems/score/scheduleredfimpl.h>
|
||||
|
||||
int _Scheduler_EDF_Compare(
|
||||
RBTree_Compare_result _Scheduler_EDF_Compare(
|
||||
const RBTree_Node* n1,
|
||||
const RBTree_Node* n2
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <rtems/score/scheduler.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
|
||||
int _Thread_queue_Compare_priority(
|
||||
RBTree_Compare_result _Thread_queue_Compare_priority(
|
||||
const RBTree_Node *left,
|
||||
const RBTree_Node *right
|
||||
)
|
||||
|
||||
@@ -94,22 +94,6 @@ static bool chunk_visitor(
|
||||
return false;
|
||||
}
|
||||
|
||||
static void test_init_chunk_alignment(void)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
rtems_rbheap_control control;
|
||||
|
||||
sc = rtems_rbheap_initialize(
|
||||
&control,
|
||||
area,
|
||||
sizeof(area),
|
||||
0,
|
||||
extend_descriptors,
|
||||
NULL
|
||||
);
|
||||
rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
|
||||
}
|
||||
|
||||
static void test_init_begin_greater_than_end(void)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
@@ -597,7 +581,6 @@ static void Init(rtems_task_argument arg)
|
||||
{
|
||||
TEST_BEGIN();
|
||||
|
||||
test_init_chunk_alignment();
|
||||
test_init_begin_greater_than_end();
|
||||
test_init_begin_greater_than_aligned_begin();
|
||||
test_init_aligned_begin_greater_than_aligned_end();
|
||||
|
||||
@@ -33,7 +33,7 @@ typedef struct {
|
||||
rtems_rbtree_node Node;
|
||||
} test_node;
|
||||
|
||||
static int test_compare_function (
|
||||
static rtems_rbtree_compare_result test_compare_function (
|
||||
const rtems_rbtree_node *n1,
|
||||
const rtems_rbtree_node *n2
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user