Go to the source code of this file.
Functions | |
void | mmDumpMemInfo (const struct mem_block *heap) |
For debuging purpose. | |
struct mem_block * | mmInit (int ofs, int size) |
input: total size in bytes return: a heap pointer if OK, NULL if error | |
static struct mem_block * | SliceBlock (struct mem_block *p, int startofs, int size, int reserved, int alignment) |
struct mem_block * | mmAllocMem (struct mem_block *heap, int size, int align2, int startSearch) |
Allocate 'size' bytes with 2^align2 bytes alignment, restrict the search to free memory after 'startSearch' depth and back buffers should be in different 4mb banks to get better page hits if possible input: size = size of block align2 = 2^align2 bytes alignment startSearch = linear offset from start of heap to begin search return: pointer to the allocated block, 0 if error. | |
struct mem_block * | mmFindBlock (struct mem_block *heap, int start) |
Free block starts at offset input: pointer to a heap, start offset return: pointer to a block. | |
static int | Join2Blocks (struct mem_block *p) |
int | mmFreeMem (struct mem_block *b) |
Free block starts at offset input: pointer to a block return: 0 if OK, -1 if error. | |
void | mmDestroy (struct mem_block *heap) |
destroy MM |
static int Join2Blocks | ( | struct mem_block * | p | ) | [static] |
Definition at line 219 of file u_mm.c.
References assert, FREE, mem_block::free, mem_block::next, mem_block::next_free, mem_block::ofs, mem_block::prev, mem_block::prev_free, and mem_block::size.
00220 { 00221 /* XXX there should be some assertions here */ 00222 00223 /* NOTE: heap->free == 0 */ 00224 00225 if (p->free && p->next->free) { 00226 struct mem_block *q = p->next; 00227 00228 assert(p->ofs + p->size == q->ofs); 00229 p->size += q->size; 00230 00231 p->next = q->next; 00232 q->next->prev = p; 00233 00234 q->next_free->prev_free = q->prev_free; 00235 q->prev_free->next_free = q->next_free; 00236 00237 FREE(q); 00238 return 1; 00239 } 00240 return 0; 00241 }
struct mem_block* mmAllocMem | ( | struct mem_block * | heap, | |
int | size, | |||
int | align2, | |||
int | startSearch | |||
) | [read] |
Allocate 'size' bytes with 2^align2 bytes alignment, restrict the search to free memory after 'startSearch' depth and back buffers should be in different 4mb banks to get better page hits if possible input: size = size of block align2 = 2^align2 bytes alignment startSearch = linear offset from start of heap to begin search return: pointer to the allocated block, 0 if error.
Definition at line 168 of file u_mm.c.
References assert, mem_block::free, mem_block::next_free, mem_block::ofs, mem_block::size, and SliceBlock().
00169 { 00170 struct mem_block *p; 00171 const int mask = (1 << align2)-1; 00172 int startofs = 0; 00173 int endofs; 00174 00175 assert(size >= 0); 00176 assert(align2 >= 0); 00177 assert(align2 <= 12); /* sanity check, 2^12 (4KB) enough? */ 00178 00179 if (!heap || align2 < 0 || size <= 0) 00180 return NULL; 00181 00182 for (p = heap->next_free; p != heap; p = p->next_free) { 00183 assert(p->free); 00184 00185 startofs = (p->ofs + mask) & ~mask; 00186 if ( startofs < startSearch ) { 00187 startofs = startSearch; 00188 } 00189 endofs = startofs+size; 00190 if (endofs <= (p->ofs+p->size)) 00191 break; 00192 } 00193 00194 if (p == heap) 00195 return NULL; 00196 00197 assert(p->free); 00198 p = SliceBlock(p,startofs,size,0,mask+1); 00199 00200 return p; 00201 }
void mmDestroy | ( | struct mem_block * | heap | ) |
destroy MM
Definition at line 273 of file u_mm.c.
References FREE, and mem_block::next.
00274 { 00275 struct mem_block *p; 00276 00277 if (!heap) 00278 return; 00279 00280 for (p = heap->next; p != heap; ) { 00281 struct mem_block *next = p->next; 00282 FREE(p); 00283 p = next; 00284 } 00285 00286 FREE(heap); 00287 }
void mmDumpMemInfo | ( | const struct mem_block * | heap | ) |
For debuging purpose.
Definition at line 34 of file u_mm.c.
References debug_printf(), mem_block::free, mem_block::next, mem_block::next_free, mem_block::ofs, mem_block::reserved, and mem_block::size.
00035 { 00036 debug_printf("Memory heap %p:\n", (void *)heap); 00037 if (heap == 0) { 00038 debug_printf(" heap == 0\n"); 00039 } else { 00040 const struct mem_block *p; 00041 00042 for(p = heap->next; p != heap; p = p->next) { 00043 debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, 00044 p->free ? 'F':'.', 00045 p->reserved ? 'R':'.'); 00046 } 00047 00048 debug_printf("\nFree list:\n"); 00049 00050 for(p = heap->next_free; p != heap; p = p->next_free) { 00051 debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, 00052 p->free ? 'F':'.', 00053 p->reserved ? 'R':'.'); 00054 } 00055 00056 } 00057 debug_printf("End of memory blocks\n"); 00058 }
Free block starts at offset input: pointer to a heap, start offset return: pointer to a block.
Definition at line 205 of file u_mm.c.
References mem_block::next, and mem_block::ofs.
00206 { 00207 struct mem_block *p; 00208 00209 for (p = heap->next; p != heap; p = p->next) { 00210 if (p->ofs == start) 00211 return p; 00212 } 00213 00214 return NULL; 00215 }
int mmFreeMem | ( | struct mem_block * | b | ) |
Free block starts at offset input: pointer to a block return: 0 if OK, -1 if error.
Definition at line 244 of file u_mm.c.
References debug_printf(), mem_block::free, mem_block::heap, Join2Blocks(), mem_block::next_free, mem_block::prev, mem_block::prev_free, and mem_block::reserved.
00245 { 00246 if (!b) 00247 return 0; 00248 00249 if (b->free) { 00250 debug_printf("block already free\n"); 00251 return -1; 00252 } 00253 if (b->reserved) { 00254 debug_printf("block is reserved\n"); 00255 return -1; 00256 } 00257 00258 b->free = 1; 00259 b->next_free = b->heap->next_free; 00260 b->prev_free = b->heap; 00261 b->next_free->prev_free = b; 00262 b->prev_free->next_free = b; 00263 00264 Join2Blocks(b); 00265 if (b->prev != b->heap) 00266 Join2Blocks(b->prev); 00267 00268 return 0; 00269 }
struct mem_block* mmInit | ( | int | ofs, | |
int | size | |||
) | [read] |
input: total size in bytes return: a heap pointer if OK, NULL if error
Definition at line 61 of file u_mm.c.
References block(), CALLOC_STRUCT, mem_block::free, FREE, mem_block::heap, mem_block::next, mem_block::next_free, mem_block::ofs, mem_block::prev, mem_block::prev_free, and mem_block::size.
00062 { 00063 struct mem_block *heap, *block; 00064 00065 if (size <= 0) 00066 return NULL; 00067 00068 heap = CALLOC_STRUCT(mem_block); 00069 if (!heap) 00070 return NULL; 00071 00072 block = CALLOC_STRUCT(mem_block); 00073 if (!block) { 00074 FREE(heap); 00075 return NULL; 00076 } 00077 00078 heap->next = block; 00079 heap->prev = block; 00080 heap->next_free = block; 00081 heap->prev_free = block; 00082 00083 block->heap = heap; 00084 block->next = heap; 00085 block->prev = heap; 00086 block->next_free = heap; 00087 block->prev_free = heap; 00088 00089 block->ofs = ofs; 00090 block->size = size; 00091 block->free = 1; 00092 00093 return heap; 00094 }
static struct mem_block* SliceBlock | ( | struct mem_block * | p, | |
int | startofs, | |||
int | size, | |||
int | reserved, | |||
int | alignment | |||
) | [static, read] |
Definition at line 98 of file u_mm.c.
References CALLOC_STRUCT, mem_block::free, mem_block::heap, mem_block::next, mem_block::next_free, mem_block::ofs, mem_block::prev, mem_block::prev_free, mem_block::reserved, and mem_block::size.
00101 { 00102 struct mem_block *newblock; 00103 00104 /* break left [p, newblock, p->next], then p = newblock */ 00105 if (startofs > p->ofs) { 00106 newblock = CALLOC_STRUCT(mem_block); 00107 if (!newblock) 00108 return NULL; 00109 newblock->ofs = startofs; 00110 newblock->size = p->size - (startofs - p->ofs); 00111 newblock->free = 1; 00112 newblock->heap = p->heap; 00113 00114 newblock->next = p->next; 00115 newblock->prev = p; 00116 p->next->prev = newblock; 00117 p->next = newblock; 00118 00119 newblock->next_free = p->next_free; 00120 newblock->prev_free = p; 00121 p->next_free->prev_free = newblock; 00122 p->next_free = newblock; 00123 00124 p->size -= newblock->size; 00125 p = newblock; 00126 } 00127 00128 /* break right, also [p, newblock, p->next] */ 00129 if (size < p->size) { 00130 newblock = CALLOC_STRUCT(mem_block); 00131 if (!newblock) 00132 return NULL; 00133 newblock->ofs = startofs + size; 00134 newblock->size = p->size - size; 00135 newblock->free = 1; 00136 newblock->heap = p->heap; 00137 00138 newblock->next = p->next; 00139 newblock->prev = p; 00140 p->next->prev = newblock; 00141 p->next = newblock; 00142 00143 newblock->next_free = p->next_free; 00144 newblock->prev_free = p; 00145 p->next_free->prev_free = newblock; 00146 p->next_free = newblock; 00147 00148 p->size = size; 00149 } 00150 00151 /* p = middle block */ 00152 p->free = 0; 00153 00154 /* Remove p from the free list: 00155 */ 00156 p->next_free->prev_free = p->prev_free; 00157 p->prev_free->next_free = p->next_free; 00158 00159 p->next_free = 0; 00160 p->prev_free = 0; 00161 00162 p->reserved = reserved; 00163 return p; 00164 }