summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/posix/include/rtems/posix/keyimpl.h6
-rw-r--r--cpukit/posix/src/key.c53
-rw-r--r--cpukit/score/include/rtems/score/freechain.h54
-rw-r--r--cpukit/score/src/freechain.c53
-rw-r--r--testsuites/sptests/spfreechain01/init.c161
-rw-r--r--testsuites/sptests/spfreechain01/spfreechain01.scn10
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 <stdbool.h>
-
+#include <rtems/score/basedefs.h>
#include <rtems/score/chain.h>
#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 <rtems/score/freechain.h>
+#include <rtems/score/assert.h>
#include <rtems/score/chainimpl.h>
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 <tmacros.h>
#include <rtems/score/chainimpl.h>
#include <rtems/score/freechain.h>
-#include <rtems/score/wkspace.h>
-#include <rtems/malloc.h>
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 ***