summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-06-24 14:00:08 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-07-01 08:24:31 +0200
commitfdb45d6b26b6e31ab168f817d25a847f1847d4a1 (patch)
treedab5ed17112f010299fe6e000cbf42263fd84315 /cpukit
parentdoc: Fix interrupt level ARM documentation (diff)
downloadrtems-fdb45d6b26b6e31ab168f817d25a847f1847d4a1.tar.bz2
score: Freechain handler API changes
Replace the extend function with an allocator since this fits better to the current use case.
Diffstat (limited to 'cpukit')
-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
4 files changed, 85 insertions, 81 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 );
}