X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fmm.c;h=d430bcdb840b9150dfc461cb5ea452d7130424da;hb=cb3a9f984de6b1a167c60c345d51d55b8c0ca80b;hp=0a71c4d8514aad22a3d329c0d02781b295c94705;hpb=2b8e66d210c333c1f9bdb4e2de079798f1c810f1;p=mesa.git diff --git a/src/mesa/main/mm.c b/src/mesa/main/mm.c index 0a71c4d8514..d430bcdb840 100644 --- a/src/mesa/main/mm.c +++ b/src/mesa/main/mm.c @@ -28,52 +28,75 @@ void mmDumpMemInfo(const struct mem_block *heap) { - const struct mem_block *p; - fprintf(stderr, "Memory heap %p:\n", (void *)heap); if (heap == 0) { fprintf(stderr, " heap == 0\n"); } else { - p = (struct mem_block *)heap; - while (p) { + const struct mem_block *p; + + for(p = heap->next; p != heap; p = p->next) { fprintf(stderr, " Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? '.':'U', + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + fprintf(stderr, "\nFree list:\n"); + + for(p = heap->next_free; p != heap; p = p->next_free) { + fprintf(stderr, " FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', p->reserved ? 'R':'.'); - p = p->next; } + } fprintf(stderr, "End of memory blocks\n"); } struct mem_block * -mmInit(int ofs, int size) +mmInit(unsigned ofs, unsigned size) { - struct mem_block *blocks; + struct mem_block *heap, *block; - if (size <= 0) { + if (!size) return NULL; - } - blocks = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block)); - if (blocks) { - blocks->ofs = ofs; - blocks->size = size; - blocks->free = 1; - return (struct mem_block *)blocks; - } - else { + + heap = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block)); + if (!heap) + return NULL; + + block = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block)); + if (!block) { + _mesa_free(heap); return NULL; } + + heap->next = block; + heap->prev = block; + heap->next_free = block; + heap->prev_free = block; + + block->heap = heap; + block->next = heap; + block->prev = heap; + block->next_free = heap; + block->prev_free = heap; + + block->ofs = ofs; + block->size = size; + block->free = 1; + + return heap; } static struct mem_block * SliceBlock(struct mem_block *p, - int startofs, int size, - int reserved, int alignment) + unsigned startofs, unsigned size, + unsigned reserved, unsigned alignment) { struct mem_block *newblock; - /* break left */ + /* break left [p, newblock, p->next], then p = newblock */ if (startofs > p->ofs) { newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block)); if (!newblock) @@ -81,13 +104,23 @@ SliceBlock(struct mem_block *p, newblock->ofs = startofs; newblock->size = p->size - (startofs - p->ofs); newblock->free = 1; + newblock->heap = p->heap; + newblock->next = p->next; - p->size -= newblock->size; + newblock->prev = p; + p->next->prev = newblock; p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size -= newblock->size; p = newblock; } - /* break right */ + /* break right, also [p, newblock, p->next] */ if (size < p->size) { newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block)); if (!newblock) @@ -95,74 +128,103 @@ SliceBlock(struct mem_block *p, newblock->ofs = startofs + size; newblock->size = p->size - size; newblock->free = 1; + newblock->heap = p->heap; + newblock->next = p->next; - p->size = size; + newblock->prev = p; + p->next->prev = newblock; p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size = size; } /* p = middle block */ - p->align = alignment; p->free = 0; + + /* Remove p from the free list: + */ + p->next_free->prev_free = p->prev_free; + p->prev_free->next_free = p->next_free; + + p->next_free = 0; + p->prev_free = 0; + p->reserved = reserved; return p; } struct mem_block * -mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) +mmAllocMem(struct mem_block *heap, unsigned size, unsigned align2, unsigned startSearch) { - struct mem_block *p = heap; - int mask = (1 << align2)-1; - int startofs = 0; - int endofs; + struct mem_block *p; + const unsigned mask = (1 << align2)-1; + unsigned startofs = 0; + unsigned endofs; - if (!heap || align2 < 0 || size <= 0) + if (!heap || !size) return NULL; - while (p) { - if ((p)->free) { - startofs = (p->ofs + mask) & ~mask; - if ( startofs < startSearch ) { - startofs = startSearch; - } - endofs = startofs+size; - if (endofs <= (p->ofs+p->size)) - break; + for (p = heap->next_free; p != heap; p = p->next_free) { + assert(p->free); + + startofs = (p->ofs + mask) & ~mask; + if ( startofs < startSearch ) { + startofs = startSearch; } - p = p->next; + endofs = startofs+size; + if (endofs <= (p->ofs+p->size)) + break; } - if (!p) + + if (p == heap) return NULL; + + assert(p->free); p = SliceBlock(p,startofs,size,0,mask+1); - p->heap = heap; + return p; } struct mem_block * -mmFindBlock(struct mem_block *heap, int start) +mmFindBlock(struct mem_block *heap, unsigned start) { - struct mem_block *p = (struct mem_block *)heap; + struct mem_block *p; - while (p) { - if (p->ofs == start && p->free) + for (p = heap->next; p != heap; p = p->next) { + if (p->ofs == start) return p; - - p = p->next; } return NULL; } -static int +static INLINE int Join2Blocks(struct mem_block *p) { /* XXX there should be some assertions here */ - if (p->free && p->next && p->next->free) { + + /* NOTE: heap->free == 0 */ + + if (p->free && p->next->free) { struct mem_block *q = p->next; + + assert(p->ofs + p->size == q->ofs); p->size += q->size; + p->next = q->next; + q->next->prev = p; + + q->next_free->prev_free = q->prev_free; + q->prev_free->next_free = q->next_free; + _mesa_free(q); return 1; } @@ -172,33 +234,28 @@ Join2Blocks(struct mem_block *p) int mmFreeMem(struct mem_block *b) { - struct mem_block *p,*prev; - if (!b) return 0; - if (!b->heap) { - fprintf(stderr, "no heap\n"); + + if (b->free) { + fprintf(stderr, "block already free\n"); return -1; } - p = b->heap; - prev = NULL; - while (p && p != b) { - prev = p; - p = p->next; - } - if (!p || p->free || p->reserved) { - if (!p) - fprintf(stderr, "block not found in heap\n"); - else if (p->free) - fprintf(stderr, "block already free\n"); - else - fprintf(stderr, "block is reserved\n"); + if (b->reserved) { + fprintf(stderr, "block is reserved\n"); return -1; } - p->free = 1; - Join2Blocks(p); - if (prev) - Join2Blocks(prev); + + b->free = 1; + b->next_free = b->heap->next_free; + b->prev_free = b->heap; + b->next_free->prev_free = b; + b->prev_free->next_free = b; + + Join2Blocks(b); + if (b->prev != b->heap) + Join2Blocks(b->prev); + return 0; } @@ -211,10 +268,11 @@ mmDestroy(struct mem_block *heap) if (!heap) return; - p = (struct mem_block *) heap; - while (p) { + for (p = heap->next; p != heap; ) { struct mem_block *next = p->next; _mesa_free(p); p = next; } + + _mesa_free(heap); }