Eli Bendersky | 3921e8e | 2010-05-21 09:05:39 +0300 | [diff] [blame] | 1 | //----------------------------------------------------------------
|
| 2 | // Statically-allocated memory manager
|
| 3 | //
|
| 4 | // by Eli Bendersky (eliben@gmail.com)
|
| 5 | //
|
| 6 | // This code is in the public domain.
|
| 7 | //----------------------------------------------------------------
|
| 8 | #ifndef MEMMGR_H
|
| 9 | #define MEMMGR_H
|
| 10 |
|
| 11 | //
|
| 12 | // Memory manager: dynamically allocates memory from
|
| 13 | // a fixed pool that is allocated statically at link-time.
|
| 14 | //
|
| 15 | // Usage: after calling memmgr_init() in your
|
| 16 | // initialization routine, just use memmgr_alloc() instead
|
| 17 | // of malloc() and memmgr_free() instead of free().
|
| 18 | // Naturally, you can use the preprocessor to define
|
| 19 | // malloc() and free() as aliases to memmgr_alloc() and
|
| 20 | // memmgr_free(). This way the manager will be a drop-in
|
| 21 | // replacement for the standard C library allocators, and can
|
| 22 | // be useful for debugging memory allocation problems and
|
| 23 | // leaks.
|
| 24 | //
|
| 25 | // Preprocessor flags you can define to customize the
|
| 26 | // memory manager:
|
| 27 | //
|
| 28 | // DEBUG_MEMMGR_FATAL
|
| 29 | // Allow printing out a message when allocations fail
|
| 30 | //
|
| 31 | // DEBUG_MEMMGR_SUPPORT_STATS
|
| 32 | // Allow printing out of stats in function
|
| 33 | // memmgr_print_stats When this is disabled,
|
| 34 | // memmgr_print_stats does nothing.
|
| 35 | //
|
| 36 | // Note that in production code on an embedded system
|
| 37 | // you'll probably want to keep those undefined, because
|
| 38 | // they cause printf to be called.
|
| 39 | //
|
| 40 | // POOL_SIZE
|
| 41 | // Size of the pool for new allocations. This is
|
| 42 | // effectively the heap size of the application, and can
|
| 43 | // be changed in accordance with the available memory
|
| 44 | // resources.
|
| 45 | //
|
| 46 | // MIN_POOL_ALLOC_QUANTAS
|
| 47 | // Internally, the memory manager allocates memory in
|
| 48 | // quantas roughly the size of two ulong objects. To
|
| 49 | // minimize pool fragmentation in case of multiple allocations
|
| 50 | // and deallocations, it is advisable to not allocate
|
| 51 | // blocks that are too small.
|
| 52 | // This flag sets the minimal ammount of quantas for
|
| 53 | // an allocation. If the size of a ulong is 4 and you
|
| 54 | // set this flag to 16, the minimal size of an allocation
|
| 55 | // will be 4 * 2 * 16 = 128 bytes
|
| 56 | // If you have a lot of small allocations, keep this value
|
| 57 | // low to conserve memory. If you have mostly large
|
| 58 | // allocations, it is best to make it higher, to avoid
|
| 59 | // fragmentation.
|
| 60 | //
|
| 61 | // Notes:
|
| 62 | // 1. This memory manager is *not thread safe*. Use it only
|
| 63 | // for single thread/task applications.
|
| 64 | //
|
| 65 |
|
| 66 | #define DEBUG_MEMMGR_SUPPORT_STATS 1
|
| 67 |
|
| 68 | #define POOL_SIZE 8 * 1024
|
| 69 | #define MIN_POOL_ALLOC_QUANTAS 16
|
| 70 |
|
| 71 |
|
| 72 | typedef unsigned char byte;
|
| 73 | typedef unsigned long ulong;
|
| 74 |
|
| 75 |
|
| 76 |
|
| 77 | // Initialize the memory manager. This function should be called
|
| 78 | // only once in the beginning of the program.
|
| 79 | //
|
| 80 | void memmgr_init();
|
| 81 |
|
| 82 | // 'malloc' clone
|
| 83 | //
|
| 84 | void* memmgr_alloc(ulong nbytes);
|
| 85 |
|
| 86 | // 'free' clone
|
| 87 | //
|
| 88 | void memmgr_free(void* ap);
|
| 89 |
|
| 90 | // Prints statistics about the current state of the memory
|
| 91 | // manager
|
| 92 | //
|
| 93 | void memmgr_print_stats();
|
| 94 |
|
| 95 |
|
| 96 | #endif // MEMMGR_H
|