diff options
Diffstat (limited to 'lib/libdrm/intel/mm.c')
-rw-r--r-- | lib/libdrm/intel/mm.c | 414 |
1 files changed, 202 insertions, 212 deletions
diff --git a/lib/libdrm/intel/mm.c b/lib/libdrm/intel/mm.c index 98146405a..106974525 100644 --- a/lib/libdrm/intel/mm.c +++ b/lib/libdrm/intel/mm.c @@ -28,254 +28,244 @@ #include "xf86drm.h" #include "mm.h" -void -mmDumpMemInfo(const struct mem_block *heap) +void mmDumpMemInfo(const struct mem_block *heap) { - drmMsg("Memory heap %p:\n", (void *)heap); - if (heap == 0) { - drmMsg(" heap == 0\n"); - } else { - const struct mem_block *p; - - for(p = heap->next; p != heap; p = p->next) { - drmMsg(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - drmMsg("\nFree list:\n"); - - for(p = heap->next_free; p != heap; p = p->next_free) { - drmMsg(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - } - drmMsg("End of memory blocks\n"); + drmMsg("Memory heap %p:\n", (void *)heap); + if (heap == 0) { + drmMsg(" heap == 0\n"); + } else { + const struct mem_block *p; + + for (p = heap->next; p != heap; p = p->next) { + drmMsg(" Offset:%08x, Size:%08x, %c%c\n", p->ofs, + p->size, p->free ? 'F' : '.', + p->reserved ? 'R' : '.'); + } + + drmMsg("\nFree list:\n"); + + for (p = heap->next_free; p != heap; p = p->next_free) { + drmMsg(" FREE Offset:%08x, Size:%08x, %c%c\n", p->ofs, + p->size, p->free ? 'F' : '.', + p->reserved ? 'R' : '.'); + } + + } + drmMsg("End of memory blocks\n"); } -struct mem_block * -mmInit(int ofs, int size) +struct mem_block *mmInit(int ofs, int size) { - struct mem_block *heap, *block; - - if (size <= 0) - return NULL; - - heap = (struct mem_block *) calloc(1, sizeof(struct mem_block)); - if (!heap) - return NULL; - - block = (struct mem_block *) calloc(1, sizeof(struct mem_block)); - if (!block) { - 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; -} + struct mem_block *heap, *block; + if (size <= 0) + return NULL; -static struct mem_block * -SliceBlock(struct mem_block *p, - int startofs, int size, - int reserved, int alignment) -{ - struct mem_block *newblock; - - /* break left [p, newblock, p->next], then p = newblock */ - if (startofs > p->ofs) { - newblock = (struct mem_block*) calloc(1, sizeof(struct mem_block)); - if (!newblock) - return NULL; - newblock->ofs = startofs; - newblock->size = p->size - (startofs - p->ofs); - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - 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, also [p, newblock, p->next] */ - if (size < p->size) { - newblock = (struct mem_block*) calloc(1, sizeof(struct mem_block)); - if (!newblock) - return NULL; - newblock->ofs = startofs + size; - newblock->size = p->size - size; - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - 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->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; + heap = (struct mem_block *)calloc(1, sizeof(struct mem_block)); + if (!heap) + return NULL; + + block = (struct mem_block *)calloc(1, sizeof(struct mem_block)); + if (!block) { + 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) +{ + struct mem_block *newblock; + + /* break left [p, newblock, p->next], then p = newblock */ + if (startofs > p->ofs) { + newblock = + (struct mem_block *)calloc(1, sizeof(struct mem_block)); + if (!newblock) + return NULL; + newblock->ofs = startofs; + newblock->size = p->size - (startofs - p->ofs); + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + 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, also [p, newblock, p->next] */ + if (size < p->size) { + newblock = + (struct mem_block *)calloc(1, sizeof(struct mem_block)); + if (!newblock) + return NULL; + newblock->ofs = startofs + size; + newblock->size = p->size - size; + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + 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->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) +struct mem_block *mmAllocMem(struct mem_block *heap, int size, int align2, + int startSearch) { - struct mem_block *p; - const int mask = (1 << align2)-1; - int startofs = 0; - int endofs; + struct mem_block *p; + const int mask = (1 << align2) - 1; + int startofs = 0; + int endofs; - if (!heap || align2 < 0 || size <= 0) - return NULL; + if (!heap || align2 < 0 || size <= 0) + return NULL; - for (p = heap->next_free; p != heap; p = p->next_free) { - assert(p->free); + for (p = heap->next_free; p != heap; p = p->next_free) { + assert(p->free); - startofs = (p->ofs + mask) & ~mask; - if ( startofs < startSearch ) { - startofs = startSearch; - } - endofs = startofs+size; - if (endofs <= (p->ofs+p->size)) - break; - } + startofs = (p->ofs + mask) & ~mask; + if (startofs < startSearch) { + startofs = startSearch; + } + endofs = startofs + size; + if (endofs <= (p->ofs + p->size)) + break; + } - if (p == heap) - return NULL; + if (p == heap) + return NULL; - assert(p->free); - p = SliceBlock(p,startofs,size,0,mask+1); + assert(p->free); + p = SliceBlock(p, startofs, size, 0, mask + 1); - return p; + return p; } - -struct mem_block * -mmFindBlock(struct mem_block *heap, int start) +struct mem_block *mmFindBlock(struct mem_block *heap, int start) { - struct mem_block *p; + struct mem_block *p; - for (p = heap->next; p != heap; p = p->next) { - if (p->ofs == start) - return p; - } + for (p = heap->next; p != heap; p = p->next) { + if (p->ofs == start) + return p; + } - return NULL; + return NULL; } - -static int -Join2Blocks(struct mem_block *p) +static int Join2Blocks(struct mem_block *p) { - /* XXX there should be some assertions here */ + /* XXX there should be some assertions here */ + + /* NOTE: heap->free == 0 */ - /* NOTE: heap->free == 0 */ + if (p->free && p->next->free) { + struct mem_block *q = p->next; - if (p->free && p->next->free) { - struct mem_block *q = p->next; + assert(p->ofs + p->size == q->ofs); + p->size += q->size; - assert(p->ofs + p->size == q->ofs); - p->size += q->size; + p->next = q->next; + q->next->prev = p; - p->next = q->next; - q->next->prev = p; + q->next_free->prev_free = q->prev_free; + q->prev_free->next_free = q->next_free; - q->next_free->prev_free = q->prev_free; - q->prev_free->next_free = q->next_free; - - free(q); - return 1; - } - return 0; + free(q); + return 1; + } + return 0; } -int -mmFreeMem(struct mem_block *b) +int mmFreeMem(struct mem_block *b) { - if (!b) - return 0; - - if (b->free) { - drmMsg("block already free\n"); - return -1; - } - if (b->reserved) { - drmMsg("block is reserved\n"); - return -1; - } - - 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; + if (!b) + return 0; + + if (b->free) { + drmMsg("block already free\n"); + return -1; + } + if (b->reserved) { + drmMsg("block is reserved\n"); + return -1; + } + + 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; } - -void -mmDestroy(struct mem_block *heap) +void mmDestroy(struct mem_block *heap) { - struct mem_block *p; + struct mem_block *p; - if (!heap) - return; + if (!heap) + return; - for (p = heap->next; p != heap; ) { - struct mem_block *next = p->next; - free(p); - p = next; - } + for (p = heap->next; p != heap;) { + struct mem_block *next = p->next; + free(p); + p = next; + } - free(heap); + free(heap); } |