Eli Bendersky | a291586 | 2012-06-23 06:25:53 +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 |