117158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca/************************************************************************** 217158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca * 3df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * Copyright (C) 1999 Wittawat Yamwong 4df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * 5df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a 6df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * copy of this software and associated documentation files (the "Software"), 7df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * to deal in the Software without restriction, including without limitation 8df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * and/or sell copies of the Software, and to permit persons to whom the 10df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * Software is furnished to do so, subject to the following conditions: 11df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * 12df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * The above copyright notice and this permission notice shall be included 13df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * in all copies or substantial portions of the Software. 14df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * 15df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 19df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca * 2317158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca **************************************************************************/ 24df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 25df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 26df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca#include "pipe/p_compiler.h" 27ea4bf267e4b023b08043f91ac44592fed1736e7fJosé Fonseca#include "util/u_debug.h" 28df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 294f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h" 3017158c2f00f5bee29ec8239367fd5498f22e4a91José Fonseca#include "util/u_mm.h" 31df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 32df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 33df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonsecavoid 343ad56968f09397a8dd417eae025b9506efaf8414Brian Paulu_mmDumpMemInfo(const struct mem_block *heap) 35df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca{ 3694726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul debug_printf("Memory heap %p:\n", (void *) heap); 37df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (heap == 0) { 38df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca debug_printf(" heap == 0\n"); 3994726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul } 4094726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul else { 41df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca const struct mem_block *p; 42d228e3cc8e7b6a3d4c6d554c5d9aed5e26be7ff0Zack Rusin int total_used = 0, total_free = 0; 43df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 4494726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul for (p = heap->next; p != heap; p = p->next) { 4594726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul debug_printf(" Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size, 4694726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul p->free ? 'F':'.', 4794726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul p->reserved ? 'R':'.'); 48d228e3cc8e7b6a3d4c6d554c5d9aed5e26be7ff0Zack Rusin if (p->free) 49d228e3cc8e7b6a3d4c6d554c5d9aed5e26be7ff0Zack Rusin total_free += p->size; 50d228e3cc8e7b6a3d4c6d554c5d9aed5e26be7ff0Zack Rusin else 51d228e3cc8e7b6a3d4c6d554c5d9aed5e26be7ff0Zack Rusin total_used += p->size; 52df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 53df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 54d228e3cc8e7b6a3d4c6d554c5d9aed5e26be7ff0Zack Rusin debug_printf("'\nMemory stats: total = %d, used = %d, free = %d\n", 55d228e3cc8e7b6a3d4c6d554c5d9aed5e26be7ff0Zack Rusin total_used + total_free, total_used, total_free); 56df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca debug_printf("\nFree list:\n"); 57df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 5894726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul for (p = heap->next_free; p != heap; p = p->next_free) { 5994726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size, 6094726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul p->free ? 'F':'.', 6194726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul p->reserved ? 'R':'.'); 62df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 63df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 64df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 65df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca debug_printf("End of memory blocks\n"); 66df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca} 67df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 6894726bc69e5f9dbefb34a38695f2f51d81ff433fBrian Paul 69df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonsecastruct mem_block * 703ad56968f09397a8dd417eae025b9506efaf8414Brian Paulu_mmInit(int ofs, int size) 71df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca{ 72df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca struct mem_block *heap, *block; 73df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 74df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (size <= 0) 75df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return NULL; 76df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 77df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca heap = CALLOC_STRUCT(mem_block); 78df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (!heap) 79df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return NULL; 80df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 81df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca block = CALLOC_STRUCT(mem_block); 82df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (!block) { 83df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca FREE(heap); 84df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return NULL; 85df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 86df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 87df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca heap->next = block; 88df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca heap->prev = block; 89df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca heap->next_free = block; 90df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca heap->prev_free = block; 91df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 92df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca block->heap = heap; 93df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca block->next = heap; 94df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca block->prev = heap; 95df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca block->next_free = heap; 96df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca block->prev_free = heap; 97df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 98df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca block->ofs = ofs; 99df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca block->size = size; 100df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca block->free = 1; 101df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 102df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return heap; 103df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca} 104df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 105df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 106df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonsecastatic struct mem_block * 107df8ab3140ce05599e1dc983ac211a30fc845d9b5José FonsecaSliceBlock(struct mem_block *p, 108df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca int startofs, int size, 109df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca int reserved, int alignment) 110df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca{ 111df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca struct mem_block *newblock; 112df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 113df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca /* break left [p, newblock, p->next], then p = newblock */ 114df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (startofs > p->ofs) { 115df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock = CALLOC_STRUCT(mem_block); 116df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (!newblock) 117df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return NULL; 118df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->ofs = startofs; 119df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->size = p->size - (startofs - p->ofs); 120df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->free = 1; 121df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->heap = p->heap; 122df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 123df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->next = p->next; 124df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->prev = p; 125df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next->prev = newblock; 126df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next = newblock; 127df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 128df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->next_free = p->next_free; 129df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->prev_free = p; 130df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next_free->prev_free = newblock; 131df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next_free = newblock; 132df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 133df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->size -= newblock->size; 134df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p = newblock; 135df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 136df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 137df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca /* break right, also [p, newblock, p->next] */ 138df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (size < p->size) { 139df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock = CALLOC_STRUCT(mem_block); 140df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (!newblock) 141df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return NULL; 142df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->ofs = startofs + size; 143df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->size = p->size - size; 144df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->free = 1; 145df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->heap = p->heap; 146df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 147df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->next = p->next; 148df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->prev = p; 149df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next->prev = newblock; 150df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next = newblock; 151df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 152df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->next_free = p->next_free; 153df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca newblock->prev_free = p; 154df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next_free->prev_free = newblock; 155df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next_free = newblock; 156df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 157df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->size = size; 158df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 159df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 160df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca /* p = middle block */ 161df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->free = 0; 162df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 163df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca /* Remove p from the free list: 164df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca */ 165df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next_free->prev_free = p->prev_free; 166df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->prev_free->next_free = p->next_free; 167df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 168df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next_free = 0; 169df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->prev_free = 0; 170df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 171df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->reserved = reserved; 172df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return p; 173df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca} 174df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 175df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 176df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonsecastruct mem_block * 1773ad56968f09397a8dd417eae025b9506efaf8414Brian Paulu_mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) 178df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca{ 179df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca struct mem_block *p; 180df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca const int mask = (1 << align2)-1; 181df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca int startofs = 0; 182df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca int endofs; 183df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 184766cb95a4564c48f35b5180155ab40320a68e371Brian Paul assert(size >= 0); 185766cb95a4564c48f35b5180155ab40320a68e371Brian Paul assert(align2 >= 0); 186766cb95a4564c48f35b5180155ab40320a68e371Brian Paul assert(align2 <= 12); /* sanity check, 2^12 (4KB) enough? */ 187766cb95a4564c48f35b5180155ab40320a68e371Brian Paul 188df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (!heap || align2 < 0 || size <= 0) 189df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return NULL; 190df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 191df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca for (p = heap->next_free; p != heap; p = p->next_free) { 192df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca assert(p->free); 193df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 194df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca startofs = (p->ofs + mask) & ~mask; 195df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if ( startofs < startSearch ) { 196df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca startofs = startSearch; 197df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 198df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca endofs = startofs+size; 199df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (endofs <= (p->ofs+p->size)) 200df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca break; 201df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 202df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 203df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (p == heap) 204df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return NULL; 205df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 206df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca assert(p->free); 207df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p = SliceBlock(p,startofs,size,0,mask+1); 208df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 209df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return p; 210df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca} 211df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 212df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 213df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonsecastruct mem_block * 2143ad56968f09397a8dd417eae025b9506efaf8414Brian Paulu_mmFindBlock(struct mem_block *heap, int start) 215df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca{ 216df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca struct mem_block *p; 217df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 218df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca for (p = heap->next; p != heap; p = p->next) { 219df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (p->ofs == start) 220df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return p; 221df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 222df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 223df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return NULL; 224df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca} 225df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 226df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 227df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonsecastatic INLINE int 228df8ab3140ce05599e1dc983ac211a30fc845d9b5José FonsecaJoin2Blocks(struct mem_block *p) 229df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca{ 230df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca /* XXX there should be some assertions here */ 231df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 232df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca /* NOTE: heap->free == 0 */ 233df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 234df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (p->free && p->next->free) { 235df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca struct mem_block *q = p->next; 236df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 237df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca assert(p->ofs + p->size == q->ofs); 238df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->size += q->size; 239df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 240df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p->next = q->next; 241df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca q->next->prev = p; 242df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 243df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca q->next_free->prev_free = q->prev_free; 244df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca q->prev_free->next_free = q->next_free; 245df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 246df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca FREE(q); 247df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return 1; 248df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 249df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return 0; 250df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca} 251df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 252df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonsecaint 2533ad56968f09397a8dd417eae025b9506efaf8414Brian Paulu_mmFreeMem(struct mem_block *b) 254df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca{ 255df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (!b) 256df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return 0; 257df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 258df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (b->free) { 259df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca debug_printf("block already free\n"); 260df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return -1; 261df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 262df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (b->reserved) { 263df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca debug_printf("block is reserved\n"); 264df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return -1; 265df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 266df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 267df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca b->free = 1; 268df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca b->next_free = b->heap->next_free; 269df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca b->prev_free = b->heap; 270df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca b->next_free->prev_free = b; 271df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca b->prev_free->next_free = b; 272df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 273df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca Join2Blocks(b); 274df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (b->prev != b->heap) 275df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca Join2Blocks(b->prev); 276df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 277df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return 0; 278df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca} 279df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 280df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 281df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonsecavoid 2823ad56968f09397a8dd417eae025b9506efaf8414Brian Paulu_mmDestroy(struct mem_block *heap) 283df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca{ 284df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca struct mem_block *p; 285df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 286df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca if (!heap) 287df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca return; 288df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 289df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca for (p = heap->next; p != heap; ) { 290df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca struct mem_block *next = p->next; 291df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca FREE(p); 292df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca p = next; 293df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca } 294df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca 295df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca FREE(heap); 296df8ab3140ce05599e1dc983ac211a30fc845d9b5José Fonseca} 297