Jason Engelman
/
mymalloc
malloc for reserved memory banks
main.cpp@0:1f96d36a994f, 2012-06-03 (annotated)
- Committer:
- tecnosys
- Date:
- Sun Jun 03 04:06:57 2012 +0000
- Revision:
- 0:1f96d36a994f
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tecnosys | 0:1f96d36a994f | 1 | #include "mbed.h" |
tecnosys | 0:1f96d36a994f | 2 | |
tecnosys | 0:1f96d36a994f | 3 | #include <stdio.h> |
tecnosys | 0:1f96d36a994f | 4 | #include <string.h> |
tecnosys | 0:1f96d36a994f | 5 | |
tecnosys | 0:1f96d36a994f | 6 | // Found on the web @ |
tecnosys | 0:1f96d36a994f | 7 | // http://simplestcodings.blogspot.com.au/2010/08/custom-malloc-function-implementation.html |
tecnosys | 0:1f96d36a994f | 8 | |
tecnosys | 0:1f96d36a994f | 9 | extern "C" void HardFault_Handler() { |
tecnosys | 0:1f96d36a994f | 10 | printf("Hard Fault!\n"); |
tecnosys | 0:1f96d36a994f | 11 | } |
tecnosys | 0:1f96d36a994f | 12 | |
tecnosys | 0:1f96d36a994f | 13 | Serial pc(USBTX, USBRX); // tx, rx |
tecnosys | 0:1f96d36a994f | 14 | |
tecnosys | 0:1f96d36a994f | 15 | char extmem[0x4000] __attribute__((section("AHBSRAM1"))); |
tecnosys | 0:1f96d36a994f | 16 | |
tecnosys | 0:1f96d36a994f | 17 | typedef |
tecnosys | 0:1f96d36a994f | 18 | struct |
tecnosys | 0:1f96d36a994f | 19 | { |
tecnosys | 0:1f96d36a994f | 20 | int is_available; |
tecnosys | 0:1f96d36a994f | 21 | int size; |
tecnosys | 0:1f96d36a994f | 22 | } MCB, *MCB_P; |
tecnosys | 0:1f96d36a994f | 23 | |
tecnosys | 0:1f96d36a994f | 24 | |
tecnosys | 0:1f96d36a994f | 25 | char *mem_start_p; |
tecnosys | 0:1f96d36a994f | 26 | int max_mem; |
tecnosys | 0:1f96d36a994f | 27 | int allocated_mem; /* this is the memory in use. */ |
tecnosys | 0:1f96d36a994f | 28 | int mcb_count; |
tecnosys | 0:1f96d36a994f | 29 | |
tecnosys | 0:1f96d36a994f | 30 | char *heap_end; |
tecnosys | 0:1f96d36a994f | 31 | |
tecnosys | 0:1f96d36a994f | 32 | MCB_P memallocate(MCB_P ,int ); |
tecnosys | 0:1f96d36a994f | 33 | |
tecnosys | 0:1f96d36a994f | 34 | enum {NEW_MCB=0,NO_MCB,REUSE_MCB}; |
tecnosys | 0:1f96d36a994f | 35 | enum {FREE,IN_USE}; |
tecnosys | 0:1f96d36a994f | 36 | |
tecnosys | 0:1f96d36a994f | 37 | |
tecnosys | 0:1f96d36a994f | 38 | void * myalloc(int elem_size) { |
tecnosys | 0:1f96d36a994f | 39 | /* check whether any chunk (allocated before) is free first */ |
tecnosys | 0:1f96d36a994f | 40 | |
tecnosys | 0:1f96d36a994f | 41 | MCB_P p_mcb; |
tecnosys | 0:1f96d36a994f | 42 | int flag = NO_MCB; |
tecnosys | 0:1f96d36a994f | 43 | int sz; |
tecnosys | 0:1f96d36a994f | 44 | |
tecnosys | 0:1f96d36a994f | 45 | p_mcb = (MCB_P)mem_start_p; |
tecnosys | 0:1f96d36a994f | 46 | |
tecnosys | 0:1f96d36a994f | 47 | |
tecnosys | 0:1f96d36a994f | 48 | sz = sizeof(MCB); |
tecnosys | 0:1f96d36a994f | 49 | |
tecnosys | 0:1f96d36a994f | 50 | if ( (elem_size + sz) > (max_mem - (allocated_mem + mcb_count * sz ) ) ) { |
tecnosys | 0:1f96d36a994f | 51 | return NULL; |
tecnosys | 0:1f96d36a994f | 52 | } |
tecnosys | 0:1f96d36a994f | 53 | while ( heap_end > ( (char *)p_mcb + elem_size + sz) ) { //<<-- problem here doesnt iterate the first block |
tecnosys | 0:1f96d36a994f | 54 | |
tecnosys | 0:1f96d36a994f | 55 | if ( p_mcb->is_available == 0) { |
tecnosys | 0:1f96d36a994f | 56 | |
tecnosys | 0:1f96d36a994f | 57 | if ( p_mcb->size == 0) { |
tecnosys | 0:1f96d36a994f | 58 | // printf("\NEW mem: %d ",p_mcb->size); |
tecnosys | 0:1f96d36a994f | 59 | flag = NEW_MCB; |
tecnosys | 0:1f96d36a994f | 60 | break; |
tecnosys | 0:1f96d36a994f | 61 | } |
tecnosys | 0:1f96d36a994f | 62 | if ( p_mcb->size >= (elem_size + sz) ) { |
tecnosys | 0:1f96d36a994f | 63 | // printf("\REUSE mem: %d ",p_mcb->size); |
tecnosys | 0:1f96d36a994f | 64 | flag = REUSE_MCB; |
tecnosys | 0:1f96d36a994f | 65 | break; |
tecnosys | 0:1f96d36a994f | 66 | } |
tecnosys | 0:1f96d36a994f | 67 | } |
tecnosys | 0:1f96d36a994f | 68 | p_mcb = (MCB_P) ( (char *)p_mcb + p_mcb->size); |
tecnosys | 0:1f96d36a994f | 69 | |
tecnosys | 0:1f96d36a994f | 70 | |
tecnosys | 0:1f96d36a994f | 71 | } |
tecnosys | 0:1f96d36a994f | 72 | |
tecnosys | 0:1f96d36a994f | 73 | if ( flag != NO_MCB) { |
tecnosys | 0:1f96d36a994f | 74 | p_mcb->is_available = 1; |
tecnosys | 0:1f96d36a994f | 75 | |
tecnosys | 0:1f96d36a994f | 76 | if ( flag == NEW_MCB) { |
tecnosys | 0:1f96d36a994f | 77 | p_mcb->size = elem_size + sizeof(MCB); |
tecnosys | 0:1f96d36a994f | 78 | } else if ( flag == REUSE_MCB) { |
tecnosys | 0:1f96d36a994f | 79 | elem_size = p_mcb->size - sizeof(MCB); |
tecnosys | 0:1f96d36a994f | 80 | } |
tecnosys | 0:1f96d36a994f | 81 | mcb_count++; |
tecnosys | 0:1f96d36a994f | 82 | allocated_mem += elem_size; |
tecnosys | 0:1f96d36a994f | 83 | return ( (char *) p_mcb + sz); |
tecnosys | 0:1f96d36a994f | 84 | } |
tecnosys | 0:1f96d36a994f | 85 | |
tecnosys | 0:1f96d36a994f | 86 | return NULL; |
tecnosys | 0:1f96d36a994f | 87 | |
tecnosys | 0:1f96d36a994f | 88 | |
tecnosys | 0:1f96d36a994f | 89 | /* if size of the available chunk is equal to greater than required size, use that chunk */ |
tecnosys | 0:1f96d36a994f | 90 | |
tecnosys | 0:1f96d36a994f | 91 | |
tecnosys | 0:1f96d36a994f | 92 | } |
tecnosys | 0:1f96d36a994f | 93 | |
tecnosys | 0:1f96d36a994f | 94 | void myfree(void *p) { |
tecnosys | 0:1f96d36a994f | 95 | /* Mark in MCB that this chunk is free */ |
tecnosys | 0:1f96d36a994f | 96 | |
tecnosys | 0:1f96d36a994f | 97 | MCB_P ptr = (MCB_P)p; |
tecnosys | 0:1f96d36a994f | 98 | ptr--; |
tecnosys | 0:1f96d36a994f | 99 | |
tecnosys | 0:1f96d36a994f | 100 | if (ptr->is_available != FREE) { |
tecnosys | 0:1f96d36a994f | 101 | mcb_count--; |
tecnosys | 0:1f96d36a994f | 102 | ptr->is_available = FREE; |
tecnosys | 0:1f96d36a994f | 103 | allocated_mem -= (ptr->size - sizeof(MCB)); |
tecnosys | 0:1f96d36a994f | 104 | } |
tecnosys | 0:1f96d36a994f | 105 | |
tecnosys | 0:1f96d36a994f | 106 | /* Mark in MCB that this chunk is free */ |
tecnosys | 0:1f96d36a994f | 107 | /* |
tecnosys | 0:1f96d36a994f | 108 | MCB_P ptr = (MCB_P)p; |
tecnosys | 0:1f96d36a994f | 109 | ptr--; |
tecnosys | 0:1f96d36a994f | 110 | |
tecnosys | 0:1f96d36a994f | 111 | mcb_count--; |
tecnosys | 0:1f96d36a994f | 112 | ptr->is_available = FREE; |
tecnosys | 0:1f96d36a994f | 113 | printf("\nAllocated mem: %d ",ptr->size); |
tecnosys | 0:1f96d36a994f | 114 | allocated_mem -= (ptr->size - sizeof(MCB)); |
tecnosys | 0:1f96d36a994f | 115 | printf("\nAllocated mem: %d ",allocated_mem); |
tecnosys | 0:1f96d36a994f | 116 | printf("\nMemory Freed..."); |
tecnosys | 0:1f96d36a994f | 117 | */ |
tecnosys | 0:1f96d36a994f | 118 | } |
tecnosys | 0:1f96d36a994f | 119 | |
tecnosys | 0:1f96d36a994f | 120 | void * myrealloc(void *p) { |
tecnosys | 0:1f96d36a994f | 121 | //I would like to implement this |
tecnosys | 0:1f96d36a994f | 122 | return NULL; |
tecnosys | 0:1f96d36a994f | 123 | } |
tecnosys | 0:1f96d36a994f | 124 | |
tecnosys | 0:1f96d36a994f | 125 | void InitMem(char *ptr, int size_in_bytes) { |
tecnosys | 0:1f96d36a994f | 126 | /* store the ptr and size_in_bytes in global variable */ |
tecnosys | 0:1f96d36a994f | 127 | |
tecnosys | 0:1f96d36a994f | 128 | max_mem = size_in_bytes; |
tecnosys | 0:1f96d36a994f | 129 | mem_start_p = ptr; |
tecnosys | 0:1f96d36a994f | 130 | mcb_count = 0; |
tecnosys | 0:1f96d36a994f | 131 | allocated_mem = 0; |
tecnosys | 0:1f96d36a994f | 132 | heap_end = mem_start_p + size_in_bytes; |
tecnosys | 0:1f96d36a994f | 133 | memset(mem_start_p,0x00,max_mem); |
tecnosys | 0:1f96d36a994f | 134 | myalloc(2); //<<-- myalloc doesnt iterate the first block, added as temporary fix |
tecnosys | 0:1f96d36a994f | 135 | /* This function is complete :-) */ |
tecnosys | 0:1f96d36a994f | 136 | |
tecnosys | 0:1f96d36a994f | 137 | } |
tecnosys | 0:1f96d36a994f | 138 | |
tecnosys | 0:1f96d36a994f | 139 | |
tecnosys | 0:1f96d36a994f | 140 | int main() { |
tecnosys | 0:1f96d36a994f | 141 | |
tecnosys | 0:1f96d36a994f | 142 | pc.baud(57600); |
tecnosys | 0:1f96d36a994f | 143 | InitMem(extmem,sizeof(extmem)); |
tecnosys | 0:1f96d36a994f | 144 | |
tecnosys | 0:1f96d36a994f | 145 | int blockSize = 256; |
tecnosys | 0:1f96d36a994f | 146 | int i = 1; |
tecnosys | 0:1f96d36a994f | 147 | |
tecnosys | 0:1f96d36a994f | 148 | printf("Checking extmem memory with blocksize %d char ...\n", blockSize); |
tecnosys | 0:1f96d36a994f | 149 | while (true) { |
tecnosys | 0:1f96d36a994f | 150 | char *p = (char *) myalloc(i * blockSize); |
tecnosys | 0:1f96d36a994f | 151 | printf("%d @ 0x%08X\n", i * blockSize, p); |
tecnosys | 0:1f96d36a994f | 152 | // printf("\nMCB count: %-3d \tAllocated Memory: %-10d",mcb_count,allocated_mem); |
tecnosys | 0:1f96d36a994f | 153 | if (p == NULL) |
tecnosys | 0:1f96d36a994f | 154 | break; |
tecnosys | 0:1f96d36a994f | 155 | myfree(p); |
tecnosys | 0:1f96d36a994f | 156 | ++i; |
tecnosys | 0:1f96d36a994f | 157 | } |
tecnosys | 0:1f96d36a994f | 158 | printf("%d\n\r",(i - 1) * blockSize); |
tecnosys | 0:1f96d36a994f | 159 | |
tecnosys | 0:1f96d36a994f | 160 | /* |
tecnosys | 0:1f96d36a994f | 161 | printf("Checking main memory with blocksize %d char ...\n", blockSize); |
tecnosys | 0:1f96d36a994f | 162 | while (true) { |
tecnosys | 0:1f96d36a994f | 163 | char *p = (char *) malloc(i * blockSize); |
tecnosys | 0:1f96d36a994f | 164 | printf("%d @ 0x%08X\n", i * blockSize, p); |
tecnosys | 0:1f96d36a994f | 165 | if (p == NULL) |
tecnosys | 0:1f96d36a994f | 166 | break; |
tecnosys | 0:1f96d36a994f | 167 | free(p); |
tecnosys | 0:1f96d36a994f | 168 | ++i; |
tecnosys | 0:1f96d36a994f | 169 | } |
tecnosys | 0:1f96d36a994f | 170 | printf("%d\n\r",(i - 1) * blockSize); |
tecnosys | 0:1f96d36a994f | 171 | */ |
tecnosys | 0:1f96d36a994f | 172 | } |
tecnosys | 0:1f96d36a994f | 173 |