3 Copyright (C) Dean Camera, 2009.
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
12 Permission to use, copy, modify, and distribute this software
13 and its documentation for any purpose and without fee is hereby
14 granted, provided that the above copyright notice appear in all
15 copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
33 * Dynamic, auto-defragmenting block memory allocator library. This library provides a convenient replacement for
34 * the standard avr-libc dynamic memory allocation routines. Memory is handed out in block chunks, to reduce the
35 * management memory overhead.
38 /** @defgroup Group_MemoryAllocator Dynamic Block Memory Allocator - LUFA/MemoryAllocator/DynAlloc.h
40 * \section Sec_Dependencies Module Source Dependencies
41 * The following files must be built with any user project that uses this module:
42 * - LUFA/MemoryAllocator/DynAlloc.c
44 * \section Module Description
45 * Dynamic, auto-defragmenting block memory allocator library. This library provides a convenient replacement for
46 * the standard avr-libc dynamic memory allocation routines. Memory is handed out in block chunks, to reduce the
47 * management memory overhead.
49 * Unlike the normal memory allocation routines, this library gives out handles to memory which must be dereferenced
50 * at the exact time of use, rather than handing back direct memory pointers. By using library managed handles
51 * instead of pointers, allocated memory blocks can be shifted around as needed transparently to defragment the
52 * memory as more blocks are requested.
54 * The memory heap is static, thus the total memory usage of the compiled application (as reported by the avr-size
55 * tool of the AVR-GCC toolchain) includes the dynamic memory heap.
57 * The constants NUM_BLOCKS, BLOCK_SIZE and NUM_HANDLES must be defined in the project makefile (and passed to the
58 * preprocessor via the -D GCC switch) for this library to compile.
60 * NUM_BLOCKS indicates the number of memory blocks in the memory psudoheap which can be chained together and handed
61 * to the application via a memory handle. NUM_HANDLES is the maximum number of memory handles (pointing to one or
62 * more chained memory blocks) which can be handed out simultaneously before requiring a handle (and its associated
63 * memory) to be freed. BLOCK_SIZE gives the number of bytes in each memory block.
76 /* Preprocessor Checks: */
77 #if (!defined(NUM_BLOCKS) || !defined(BLOCK_SIZE) || !defined(NUM_HANDLES))
78 #error NUM_BLOCKS, BLOCK_SIZE and NUM_HANDLES must be defined before use via makefile.
81 /* Public Interface - May be used in end-application: */
83 /** Macro to dereference a given memory handle into the given type. The given type should be a pointer
84 * if the memory is to contain an array of items, or should be a standard type (such as a primitive or
85 * structure) if the memory is to hold a single item of a single type. */
86 #define DEREF(handle, type) (*(type*)handle)
88 /** Constant, giving the total heap size in bytes. */
89 #define ALLOCABLE_BYTES (1UL * NUM_BLOCKS * BLOCK_SIZE)
92 /** Memory handle type, used to store handles given by the library functions. */
93 typedef const void** Mem_Handle_t
;
95 #if (ALLOCABLE_BYTES > 0xFFFF) || defined(__DOXYGEN__)
96 /** Type define for the size (in bytes) for an allocation for passing to the library functions.
97 * The exact type width varies depending on the value of ALLOCABLE_BYTES to ensure that a single
98 * allocation can request the entire heap if needed.
100 typedef uint32_t Alloc_Size_t
;
101 #elif (ALLOCABLE_BYTES > 0xFF)
102 typedef uint16_t Alloc_Size_t
;
104 typedef uint8_t Alloc_Size_t
;
107 #if (NUM_BLOCKS > 0xFFFF) || defined(__DOXYGEN__)
108 /** Type define for a block number in the heap. The exact type width varies depending on the
109 * value of NUM_BLOCKS to ensure that the type can store an index to any block in the block pool.
111 typedef uint32_t Block_Number_t
;
112 #elif (NUM_BLOCKS > 0xFF)
113 typedef uint16_t Block_Number_t
;
115 typedef uint8_t Block_Number_t
;
118 #if (NUM_HANDLES > 0xFFFF) || defined(__DOXYGEN__)
119 /** Type define for a handle number. The exact type width varies depending on the value of NUM_HANDLES
120 * to ensure that the type can store the index of any handle in the handle pool.
122 typedef uint32_t Handle_Number_t
;
123 #elif (NUM_HANDLES > 0xFF)
124 typedef uint16_t Handle_Number_t
;
126 typedef uint8_t Handle_Number_t
;
129 /* Function Prototypes: */
130 /** Allocates a given number of blocks from the heap (calculated from the requested number of bytes) and
131 * returns a handle to the newly allocated memory.
133 * \param Bytes The number of bytes requested to be allocated from the heap
135 * \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
137 Mem_Handle_t
Mem_Alloc(const Alloc_Size_t Bytes
);
139 /** Allocates a given number of blocks from the heap (calculated from the requested number of bytes) and
140 * returns a handle to the newly allocated memory. Calloced memory is automatically cleared to all 0x00
141 * values at the time of allocation.
143 * \param Bytes The number of pre-cleared bytes requested to be allocated from the heap
145 * \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
147 Mem_Handle_t
Mem_Calloc(const Alloc_Size_t Bytes
);
149 /** Deallocates a given memory handle, and attempts to allocates the given number of blocks from the heap
150 * (calculated from the requested number of bytes) immediately following the deallocation. The new memory
151 * may be located in the same area as the previous memory, but this is not guaranteed.
153 * \param CurrAllocHdl Handle to an already allocated section of memory in the heap to deallocate
154 * \param Bytes The number of bytes requested to be allocated from the heap following the
157 * \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
159 * \warning Even if the allocation fails, the deallocation will still occur. Care should be taken to ensure
160 * that the previously allocated memory is not used following an unsuccessful realloc().
162 Mem_Handle_t
Mem_Realloc(Mem_Handle_t CurrAllocHdl
, const Alloc_Size_t Bytes
);
164 /** Deallocates a given previously allocated section of memory from the heap.
166 * \param CurrAllocHdl Handle to a previously allocated section of memory in the heap
168 void Mem_Free(Mem_Handle_t CurrAllocHdl
);
170 /** Returns the total number of unallocated blocks in the heap.
172 * \return Number of free blocks in the heap, as a Block_Number_t integer
174 Block_Number_t
Mem_TotalFreeBlocks(void);
176 /** Returns the total number of unallocated handles in the handle pool.
178 * \return Number of free handles in the handle pool, as a Handle_Number_t integer
180 Handle_Number_t
Mem_TotalFreeHandles(void);
182 /* Private Interface - For use in library only: */
183 #if !defined(__DOXYGEN__)
185 #define BLOCK_USED_MASK (1 << 0)
186 #define BLOCK_LINKED_MASK (1 << 1)
188 /* Function Prototypes: */
189 #if defined(INCLUDE_FROM_DYNALLOC_C)
190 static uint8_t Mem_GetBlockFlags(const Block_Number_t BlockNum
);
191 static void Mem_SetBlockFlags(const Block_Number_t BlockNum
, const uint8_t Flags
);
192 static void Mem_Defrag(void);