summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/freechain.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/src/freechain.c')
-rw-r--r--cpukit/score/src/freechain.c53
1 files changed, 42 insertions, 11 deletions
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 );
}