/* * lub_partition.c */ /** \ingroup lub \defgroup lub_heap heap @{ \brief A thread safe dynamic memory alloction system for use in a multitasking operating system. This is a high level client of the lub_heap component and provides the following additional features: \section auto_resources Automatically obtains its resources The client doesn't need to provide memory storage for this partition. It will automatically obtain this from the system pool (malloc/free etc) \section performance Multi-threading performance If cache details are provided then a small high performance heap, just big enough to hold the cache, is created on a per thread basis. This is referenced using thread specific storage within the owning thread and if it is unable to satisfy the request then a slower mutex locked global heap is created and used instead. \section auto_extension Automatically extends itself - The (slower) global heap will automatically extend itself as needed. \author Graeme McKerrell \date Created On : Wed Jun 27 14:00:00 2007 \version UNTESTED */ #ifndef _lub_partition_h #define _lub_partition_h #include #include "lub/types.h" #include "lub/c_decl.h" #include "lub/heap.h" _BEGIN_C_DECL /** * This type is used to reference an instance of a heap. */ typedef struct _lub_partition lub_partition_t; /** * This type defines a fundamental allocation function which * can be used to extend the partition as needed. */ typedef void *lub_partition_sysalloc_fn(size_t required); /** * This type is used to specify any local requirements */ typedef struct _lub_partition_spec lub_partition_spec_t; struct _lub_partition_spec { /** * Indicates whether or not to use a thread specific heap will be created * for each client of the partition. */ bool_t use_local_heap; /** * The maximum block size for the local heap. */ lub_heap_align_t max_local_block_size; /** * The number of maximum sized blocks to make available. * * If this is non zero then a local heap containing a cache with * (num_max_block * max_block_size) size buckets will be created * * If this is zero then a local heap of size max_block_size * will be created (without a cache) */ size_t num_local_max_blocks; /** * When the partition grows each new segment will be at least this many bytes in size */ size_t min_segment_size; /** * The limit in total bytes which can be allocated from the malloc hook * for the growth of this partition */ size_t memory_limit; /** * If non-NULL then this pointer references the fundamental memory allocation * function which should be used to extend the partition. * If NULL then the standard 'malloc' function will be used. */ lub_partition_sysalloc_fn *sysalloc; }; /** * This operation creates a partition * * \pre * - The system pool needs to be accessible * * \return * - a reference to a partition object which can be used to allocate * memory * * \post * - memory allocations can be invoked on the returned intance. */ lub_partition_t *lub_partition_create( /** * This is used to specify the details to be used for * the partition. */ const lub_partition_spec_t * spec); /** * This operation starts the process of killing a partition. * * \pre * - The partition needs to have been created. * * \return * - none * * \post * - The partition will no longer hand out memory. * - When the final outstanding piece of memory is handed back * the partition will destroy itself. * - Upon final destruction any resources obtained from the * system pool will be returned. */ void lub_partition_kill( /** * The heap instance on which to operate */ lub_partition_t * instance); /** * This operation changes the size of the object referenced by a passed in * pointer to "size". The contents will be unchanged up to the minimum of the old * and new sizes. If the new size is larger, the new space is uninitialised. * * \pre * - The partition needs to have been created. * - If "*ptr" contains a non-NULL value then this MUST have * been allocated using this operation, from the same heap instance. * * \return * - the status of the operation. * * \post * - The client takes responsiblity for releasing any allocated memory when they * are finished with it. * - If *ptr contains a non-NULL value, then after a succesfull call, the * initial memory referenced by it may have been released for reuse, * and the pointer modified to reference some new memory. * - *ptr may contain NULL in which case no memory will be released back to the * heap for reuse, and the pointer is filled out with the allocated memory. * - (size == 0) No new memory will be allocated, *ptr will be set to NULL, * and any original memory referenced by it will have been released. */ lub_heap_status_t lub_partition_realloc( /** * The partition instance on which to operate */ lub_partition_t * instance, /** * Reference to a pointer containing previously allocated memory * or NULL. */ char **ptr, /** * The number of bytes required for the object */ size_t size, /** * The alignment required for a new allocations. */ lub_heap_align_t alignment); /** * This operation checks the integrety of the memory in the specified * partition. * Corruption will be spotted the first time a check is performed AFTER * it has occured. * \pre * - the specified partition will have been created * * \return * - BOOL_TRUE if the partition is OK * - BOOL_FALSE if the partition is corrupted. * * \post * - none */ extern bool_t lub_partition_check_memory(lub_partition_t * instance); /** * This operation dumps the salient details of the specified partition to stdout */ void lub_partition_show( /** * The instance on which to operate */ lub_partition_t * instance, /** * Whether to be verbose or not */ bool_t verbose); /** * This function is invoked whenever a call to lub_partition_realloc() * fails. * It is provided as a debugging aid; simple set a breakpoint to * stop execution of the program and any failures will be caught in context. */ void lub_partition_stop_here( /** * The failure status of the the call to realloc */ lub_heap_status_t status, /** * The old value of the pointer passed in */ char *old_ptr, /** * The requested number of bytes */ size_t new_size); /** * This causes leak detection to be disabled for this partition */ void lub_partition_disable_leak_detection( /** * The instance on which to operate */ lub_partition_t * instance); /** * This causes leak detection to be enabled for this partition */ void lub_partition_enable_leak_detection( /** * The instance on which to operate */ lub_partition_t * instance); _END_C_DECL #endif /* _lub_partition_h */ /** @} */