From fdb45d6b26b6e31ab168f817d25a847f1847d4a1 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 24 Jun 2015 14:00:08 +0200 Subject: score: Freechain handler API changes Replace the extend function with an allocator since this fits better to the current use case. --- cpukit/posix/include/rtems/posix/keyimpl.h | 6 +- cpukit/posix/src/key.c | 53 ++----- cpukit/score/include/rtems/score/freechain.h | 54 +++---- cpukit/score/src/freechain.c | 53 +++++-- testsuites/sptests/spfreechain01/init.c | 161 ++------------------- testsuites/sptests/spfreechain01/spfreechain01.scn | 10 +- 6 files changed, 104 insertions(+), 233 deletions(-) diff --git a/cpukit/posix/include/rtems/posix/keyimpl.h b/cpukit/posix/include/rtems/posix/keyimpl.h index a5c80d625b..6fd4d1348a 100644 --- a/cpukit/posix/include/rtems/posix/keyimpl.h +++ b/cpukit/posix/include/rtems/posix/keyimpl.h @@ -156,11 +156,7 @@ RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Get ( _Objects_Get( &_POSIX_Keys_Information, (Objects_Id) id, location ); } -RTEMS_INLINE_ROUTINE POSIX_Keys_Key_value_pair * -_POSIX_Keys_Key_value_pair_allocate( void ) -{ - return (POSIX_Keys_Key_value_pair *) _Freechain_Get( &_POSIX_Keys_Keypool ); -} +POSIX_Keys_Key_value_pair * _POSIX_Keys_Key_value_pair_allocate( void ); RTEMS_INLINE_ROUTINE void _POSIX_Keys_Key_value_pair_free( POSIX_Keys_Key_value_pair *key_value_pair diff --git a/cpukit/posix/src/key.c b/cpukit/posix/src/key.c index 6753d57437..55c6590051 100644 --- a/cpukit/posix/src/key.c +++ b/cpukit/posix/src/key.c @@ -92,49 +92,24 @@ static uint32_t _POSIX_Keys_Get_initial_keypool_size( void ) return _Objects_Maximum_per_allocation( max ); } -static bool _POSIX_Keys_Keypool_extend( Freechain_Control *keypool ) +static void _POSIX_Keys_Initialize_keypool( void ) { - size_t bump_count = _POSIX_Keys_Get_keypool_bump_count(); - bool ok = bump_count > 0; - - if ( ok ) { - size_t size = bump_count * sizeof( POSIX_Keys_Key_value_pair ); - POSIX_Keys_Key_value_pair *nodes = _Workspace_Allocate( size ); - - ok = nodes != NULL; - - if ( ok ) { - _Chain_Initialize( - &keypool->Freechain, - nodes, - bump_count, - sizeof( *nodes ) - ); - } - } - - return ok; + _Freechain_Initialize( + &_POSIX_Keys_Keypool, + _Workspace_Allocate_or_fatal_error, + _POSIX_Keys_Get_initial_keypool_size(), + sizeof( POSIX_Keys_Key_value_pair ) + ); } -static void _POSIX_Keys_Initialize_keypool( void ) +POSIX_Keys_Key_value_pair * _POSIX_Keys_Key_value_pair_allocate( void ) { - Freechain_Control *keypool = &_POSIX_Keys_Keypool; - size_t initial_count = _POSIX_Keys_Get_initial_keypool_size(); - - _Freechain_Initialize( keypool, _POSIX_Keys_Keypool_extend ); - - if ( initial_count > 0 ) { - size_t size = initial_count * sizeof( POSIX_Keys_Key_value_pair ); - POSIX_Keys_Key_value_pair *nodes = - _Workspace_Allocate_or_fatal_error( size ); - - _Chain_Initialize( - &keypool->Freechain, - nodes, - initial_count, - sizeof( *nodes ) - ); - } + return (POSIX_Keys_Key_value_pair *) _Freechain_Get( + &_POSIX_Keys_Keypool, + _Workspace_Allocate, + _POSIX_Keys_Get_keypool_bump_count(), + sizeof( POSIX_Keys_Key_value_pair ) + ); } /** diff --git a/cpukit/score/include/rtems/score/freechain.h b/cpukit/score/include/rtems/score/freechain.h index d68a1f7c8c..7fa580a4e1 100644 --- a/cpukit/score/include/rtems/score/freechain.h +++ b/cpukit/score/include/rtems/score/freechain.h @@ -16,8 +16,7 @@ #ifndef _RTEMS_SCORE_FREECHAIN_H #define _RTEMS_SCORE_FREECHAIN_H -#include - +#include #include #ifdef __cplusplus @@ -36,27 +35,20 @@ extern "C" { * @{ */ -typedef struct Freechain_Control Freechain_Control; - /** - * @brief Extends the freechain. - * - * @param[in] freechain The freechain control. - * - * @retval true The freechain contains now at least one node. - * @retval false Otherwise. + * @brief Allocator function. */ -typedef bool ( *Freechain_Extend )( Freechain_Control *freechain ); +typedef void *( *Freechain_Allocator )( size_t size ); /** - * @typedef Freechain_Control - * - * This is used to manage freechain's nodes. + * @brief The freechain control. */ -struct Freechain_Control { - Chain_Control Freechain; - Freechain_Extend extend; -}; +typedef struct { + /** + * @brief Chain of free nodes. + */ + Chain_Control Free; +} Freechain_Control; /** * @brief Initializes a freechain. @@ -65,32 +57,42 @@ struct Freechain_Control { * of nodes. In case the freechain is empty the extend handler is called to * get more nodes. * - * @param[in,out] freechain The freechain control to initialize. - * @param[in] extend The extend handler. It is called by _Freechain_Get() in - * case the freechain is empty. + * @param[in] freechain The freechain control to initialize. + * @param[in] allocator The allocator function. + * @param[in] number_nodes The initial number of nodes. + * @param[in] node_size The node size. */ void _Freechain_Initialize( - Freechain_Control *freechain, - Freechain_Extend extend + Freechain_Control *freechain, + Freechain_Allocator allocator, + size_t number_nodes, + size_t node_size ); /** * @brief Gets a node from the freechain. * - * @param[in,out] freechain The freechain control. + * @param[in] freechain The freechain control. + * @param[in] allocator The allocator function. + * @param[in] number_nodes_to_extend The number of nodes in case an extend is + * necessary due to an empty freechain. + * @param[in] node_size The node size. * * @retval NULL The freechain is empty and the extend operation failed. * @retval otherwise Pointer to a node. The node ownership passes to the * caller. */ void *_Freechain_Get( - Freechain_Control *freechain + Freechain_Control *freechain, + Freechain_Allocator allocator, + size_t number_nodes_to_extend, + size_t node_size ); /** * @brief Puts a node back onto the freechain. * - * @param[in,out] freechain The freechain control. + * @param[in] freechain The freechain control. * @param[in] node The node to put back. */ void _Freechain_Put( diff --git a/cpukit/score/src/freechain.c b/cpukit/score/src/freechain.c index 58935fadd3..84b4c63461 100644 --- a/cpukit/score/src/freechain.c +++ b/cpukit/score/src/freechain.c @@ -19,29 +19,60 @@ #endif #include +#include #include void _Freechain_Initialize( - Freechain_Control *freechain, - Freechain_Extend extend + Freechain_Control *freechain, + Freechain_Allocator allocator, + size_t number_nodes, + size_t node_size ) { - _Chain_Initialize_empty( &freechain->Freechain ); - freechain->extend = extend; + void *starting_address; + + if ( number_nodes > 0 ) { + starting_address = ( *allocator )( number_nodes * node_size ); + number_nodes *= ( starting_address != NULL ); + } else { + starting_address = NULL; + } + + _Chain_Initialize( + &freechain->Free, + starting_address, + number_nodes, + node_size + ); } -void *_Freechain_Get(Freechain_Control *freechain) +void *_Freechain_Get( + Freechain_Control *freechain, + Freechain_Allocator allocator, + size_t number_nodes_to_extend, + size_t node_size +) { - if ( _Chain_Is_empty( &freechain->Freechain ) ) { - if ( !( *freechain->extend )( freechain ) ) { - return NULL; - } + _Assert( node_size >= sizeof( Chain_Node ) ); + + if ( _Chain_Is_empty( &freechain->Free ) && number_nodes_to_extend > 0 ) { + void *starting_address; + + starting_address = ( *allocator )( number_nodes_to_extend * node_size ); + number_nodes_to_extend *= ( starting_address != NULL ); + + _Chain_Initialize( + &freechain->Free, + starting_address, + number_nodes_to_extend, + node_size + ); } - return _Chain_Get_first_unprotected( &freechain->Freechain ); + return _Chain_Get_unprotected( &freechain->Free ); } void _Freechain_Put( Freechain_Control *freechain, void *node ) { - _Chain_Prepend_unprotected( &freechain->Freechain, node ); + _Chain_Prepend_unprotected( &freechain->Free, node ); } diff --git a/testsuites/sptests/spfreechain01/init.c b/testsuites/sptests/spfreechain01/init.c index 8f5e10f28d..8963752d00 100644 --- a/testsuites/sptests/spfreechain01/init.c +++ b/testsuites/sptests/spfreechain01/init.c @@ -13,171 +13,43 @@ #include #include #include -#include -#include const char rtems_test_name[] = "SPFREECHAIN 1"; -/* forward declarations to avoid warnings */ -rtems_task Init(rtems_task_argument argument); -bool my_freechain_extend_with_nothing( Freechain_Control *freechain ); -bool my_freechain_extend_heap( Freechain_Control *freechain ); -bool my_freechain_extend_workspace( Freechain_Control *freechain ); -void my_freechain_init_heap( Freechain_Control *freechain ); -void my_freechain_init_workspace( Freechain_Control *freechain ); - -typedef struct { - Freechain_Control super_fc; - size_t bump_count; -} MyFreechain; - typedef struct { - Chain_Node ch_node; + Chain_Node Node; int x; } test_node; -bool my_freechain_extend_with_nothing( Freechain_Control *freechain ) -{ - return NULL; -} - -/* user defined extend handle, it allocates memory on heap. */ -bool my_freechain_extend_heap( Freechain_Control *freechain ) +static rtems_task Init(rtems_task_argument ignored) { - MyFreechain *self = (MyFreechain *)freechain; - size_t node_size = sizeof(test_node); - size_t size = self->bump_count * node_size; - int i; - test_node *nodes = malloc(size); - - if (!nodes) { - printf( "INIT - Unable to allocate free chain of size: %zd\n", size ); - return NULL; - } - - puts( "INIT - Allocate node from heap in user defined freechain extend" - " - OK" ); - for ( i = 0; i < self->bump_count; i++ ) { - _Freechain_Put(freechain, - nodes + i); - } - return true; -} + Freechain_Control fc; + test_node *node; -/* user defined extend handle, it allocates memory on workspace. */ -bool my_freechain_extend_workspace( Freechain_Control *freechain ) -{ - MyFreechain *self = (MyFreechain *)freechain; - size_t node_size = sizeof(test_node); - size_t size = self->bump_count * node_size; - int i; - test_node *nodes = _Workspace_Allocate(size); - - if (!nodes) { - printf( "INIT - Unable to allocate free chain of size: %zd\n", size ); - return NULL; - } - - puts( "INIT - Allocate node from workspace in user defined freechain extend" - " - OK" ); - - for ( i = 0; i < self->bump_count; i++ ) { - _Freechain_Put(freechain, - nodes + i); - } - return true; -} + TEST_BEGIN(); -void my_freechain_init_heap( Freechain_Control *freechain ) -{ - MyFreechain *self = (MyFreechain *)freechain; - self->bump_count = 5; - size_t size = self->bump_count * sizeof(test_node); - test_node *nodes = malloc(size); - - _Chain_Initialize( - &freechain->Freechain, - nodes, - self->bump_count, - sizeof(test_node) - ); -} + _Freechain_Initialize(&fc, NULL, 0, sizeof(test_node)); + rtems_test_assert(_Chain_Is_empty(&fc.Free)); -void my_freechain_init_workspace( Freechain_Control *freechain ) -{ - MyFreechain *self = (MyFreechain *)freechain; - self->bump_count = 7; - size_t size = self->bump_count * sizeof(test_node); - test_node *nodes = _Workspace_Allocate(size); - - _Chain_Initialize( - &freechain->Freechain, - nodes, - self->bump_count, - sizeof(test_node) - ); -} + _Freechain_Initialize(&fc, malloc, 1, SIZE_MAX); + rtems_test_assert(_Chain_Is_empty(&fc.Free)); -rtems_task Init( - rtems_task_argument ignored - ) -{ - TEST_BEGIN(); + rtems_test_assert(_Freechain_Get(&fc, NULL, 0, sizeof(test_node)) == NULL); - test_node *test_node_p; - MyFreechain myfc; - Freechain_Control *fc_p = (Freechain_Control *)&myfc; - int i; + rtems_test_assert(_Freechain_Get(&fc, malloc, 1, SIZE_MAX) == NULL); /* check whether freechain put and get works correctly*/ - _Freechain_Initialize(fc_p, - &my_freechain_extend_with_nothing); - my_freechain_init_heap(fc_p); puts( "INIT - Get node from freechain - OK" ); - test_node_p = (test_node *)_Freechain_Get(fc_p); - test_node_p->x = 1; + node = _Freechain_Get(&fc, malloc, 1, sizeof(test_node)); + node->x = 1; puts( "INIT - Put node back to freechain - OK" ); - _Freechain_Put(fc_p, (void *)test_node_p); + _Freechain_Put(&fc, node); puts( "INIT - Verify freechain node put and get - OK" ); - test_node_p = (test_node *)_Freechain_Get(fc_p); - if(test_node_p->x != 1) { - puts( "INIT - ERROR ON FREECHAIN GET AND PUT" ); - rtems_test_exit(0); - } - - /* check whether freechain extend handle on heap works correctly */ - _Freechain_Initialize(fc_p, - &my_freechain_extend_heap); - my_freechain_init_heap(fc_p); - - puts( "INIT - Get more than intialized nodes from freechain on heap - OK" ); - - for ( i = 0; i < myfc.bump_count * 2; i++ ) { - test_node_p = (test_node *)_Freechain_Get(fc_p); - if (!test_node_p) { - puts( "INIT - Get node from freechain failed - FAILED" ); - rtems_test_exit(0); - } - } - - /* check whether freechain extend handle in workspace works correctly */ - _Freechain_Initialize(fc_p, - &my_freechain_extend_workspace); - my_freechain_init_workspace(fc_p); - - puts( "INIT - Get more than intialized nodes from freechain in workspace" - " - OK" ); - - for ( i = 0; i < myfc.bump_count * 2; i++ ) { - test_node_p = (test_node *)_Freechain_Get(fc_p); - if (!test_node_p) { - puts( "INIT - Get node from freechain failed - FAILED" ); - rtems_test_exit(0); - } - } + node = _Freechain_Get(&fc, NULL, 0, sizeof(test_node)); + rtems_test_assert(node->x == 1); TEST_END(); rtems_test_exit(0); @@ -188,7 +60,6 @@ rtems_task Init( #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER -#define CONFIGURE_MEMORY_OVERHEAD sizeof(test_node) #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION #define CONFIGURE_RTEMS_INIT_TASKS_TABLE diff --git a/testsuites/sptests/spfreechain01/spfreechain01.scn b/testsuites/sptests/spfreechain01/spfreechain01.scn index e65e90a6e3..d6e82c8d5c 100644 --- a/testsuites/sptests/spfreechain01/spfreechain01.scn +++ b/testsuites/sptests/spfreechain01/spfreechain01.scn @@ -1,9 +1,5 @@ -*** START OF RTEMS FREECHAIN API TEST *** +*** BEGIN OF TEST SPFREECHAIN 1 *** INIT - Get node from freechain - OK -INIT - Put node to freechain - OK +INIT - Put node back to freechain - OK INIT - Verify freechain node put and get - OK -INIT - Get more than intialized nodes from freechain on heap - OK -INIT - Allocate node from heap in user defined freechain extend - OK -INIT - Get more than intialized nodes from freechain in workspace - OK -INIT - Allocate node from workspace in user defined freechain extend - OK -*** END OF RTEMS FREECHAIN API TEST *** \ No newline at end of file +*** END OF TEST SPFREECHAIN 1 *** -- cgit v1.2.3