193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell/* 293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * GLX Hardware Device Driver common code 393a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * Copyright (C) 1999 Wittawat Yamwong 493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * 593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 693a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * copy of this software and associated documentation files (the "Software"), 793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * to deal in the Software without restriction, including without limitation 893a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 993a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 1093a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * Software is furnished to do so, subject to the following conditions: 1193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * 1293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * The above copyright notice and this permission notice shall be included 1393a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * in all copies or substantial portions of the Software. 1493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * 1593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1693a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1893a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 1993a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2093a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 2193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell * 2393a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell */ 2493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 25ca2ceca5b1939af57e95bebf84be4b70e3e9d4cbVinson Lee#include <assert.h> 26ca2ceca5b1939af57e95bebf84be4b70e3e9d4cbVinson Lee#include <stdio.h> 27ca2ceca5b1939af57e95bebf84be4b70e3e9d4cbVinson Lee#include <stdlib.h> 28ca2ceca5b1939af57e95bebf84be4b70e3e9d4cbVinson Lee 29ca2ceca5b1939af57e95bebf84be4b70e3e9d4cbVinson Lee#include "compiler.h" 3093a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell#include "mm.h" 3193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 3293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 331c236fd5c734b7388d7625ce8c3d4b2d6da9fcfbBrian Paulvoid 342b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith WhitwellmmDumpMemInfo(const struct mem_block *heap) 3593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell{ 36bcc6eddd335e97d49ed2ef3a1440f94d58dce12dJon Smirl fprintf(stderr, "Memory heap %p:\n", (void *)heap); 3793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell if (heap == 0) { 3893a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell fprintf(stderr, " heap == 0\n"); 3993a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } else { 407e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell const struct mem_block *p; 417e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 427e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell for(p = heap->next; p != heap; p = p->next) { 437e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell fprintf(stderr, " Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, 447e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->free ? 'F':'.', 457e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->reserved ? 'R':'.'); 467e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell } 477e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 487e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell fprintf(stderr, "\nFree list:\n"); 497e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 507e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell for(p = heap->next_free; p != heap; p = p->next_free) { 51c26f36c830cc6df1093a145eb43645f535004eb7Keith Whitwell fprintf(stderr, " FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, 527e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->free ? 'F':'.', 5393a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell p->reserved ? 'R':'.'); 5493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } 557e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 5693a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } 5793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell fprintf(stderr, "End of memory blocks\n"); 5893a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell} 5993a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 602b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith Whitwellstruct mem_block * 6160325331a8a76f3c783284c65b81cee471d7d64cJosé FonsecammInit(unsigned ofs, unsigned size) 6293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell{ 637e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell struct mem_block *heap, *block; 6493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 6560325331a8a76f3c783284c65b81cee471d7d64cJosé Fonseca if (!size) 66934be3266fe7c873f8fa1154af20d378282d2d47Dave Airlie return NULL; 677e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 682b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner heap = calloc(1, sizeof(struct mem_block)); 697e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell if (!heap) 707e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell return NULL; 717e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 722b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner block = calloc(1, sizeof(struct mem_block)); 737e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell if (!block) { 7432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(heap); 75934be3266fe7c873f8fa1154af20d378282d2d47Dave Airlie return NULL; 761c236fd5c734b7388d7625ce8c3d4b2d6da9fcfbBrian Paul } 777e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 787e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell heap->next = block; 797e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell heap->prev = block; 807e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell heap->next_free = block; 817e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell heap->prev_free = block; 827e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 837e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell block->heap = heap; 847e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell block->next = heap; 857e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell block->prev = heap; 867e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell block->next_free = heap; 877e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell block->prev_free = heap; 887e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 897e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell block->ofs = ofs; 907e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell block->size = size; 917e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell block->free = 1; 927e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 93c26f36c830cc6df1093a145eb43645f535004eb7Keith Whitwell return heap; 9493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell} 9593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 9693a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 972b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith Whitwellstatic struct mem_block * 982b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith WhitwellSliceBlock(struct mem_block *p, 9960325331a8a76f3c783284c65b81cee471d7d64cJosé Fonseca unsigned startofs, unsigned size, 10060325331a8a76f3c783284c65b81cee471d7d64cJosé Fonseca unsigned reserved, unsigned alignment) 10193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell{ 1022b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith Whitwell struct mem_block *newblock; 10393a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 1047e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell /* break left [p, newblock, p->next], then p = newblock */ 10593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell if (startofs > p->ofs) { 1062b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner newblock = calloc(1, sizeof(struct mem_block)); 10793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell if (!newblock) 10893a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return NULL; 10993a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell newblock->ofs = startofs; 11093a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell newblock->size = p->size - (startofs - p->ofs); 11193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell newblock->free = 1; 1127e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell newblock->heap = p->heap; 1137e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 11493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell newblock->next = p->next; 1157e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell newblock->prev = p; 1167e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->next->prev = newblock; 11793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell p->next = newblock; 1187e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 1197e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell newblock->next_free = p->next_free; 1207e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell newblock->prev_free = p; 1217e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->next_free->prev_free = newblock; 1227e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->next_free = newblock; 1237e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 1247e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->size -= newblock->size; 12593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell p = newblock; 12693a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } 12793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 128c26f36c830cc6df1093a145eb43645f535004eb7Keith Whitwell /* break right, also [p, newblock, p->next] */ 12993a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell if (size < p->size) { 1302b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner newblock = calloc(1, sizeof(struct mem_block)); 13193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell if (!newblock) 13293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return NULL; 13393a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell newblock->ofs = startofs + size; 13493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell newblock->size = p->size - size; 13593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell newblock->free = 1; 1367e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell newblock->heap = p->heap; 1377e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 13893a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell newblock->next = p->next; 1397e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell newblock->prev = p; 1407e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->next->prev = newblock; 14193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell p->next = newblock; 1427e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 1437e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell newblock->next_free = p->next_free; 1447e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell newblock->prev_free = p; 1457e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->next_free->prev_free = newblock; 1467e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->next_free = newblock; 1477e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 1487e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->size = size; 14993a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } 15093a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 15193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell /* p = middle block */ 15293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell p->free = 0; 1537e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 1547e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell /* Remove p from the free list: 1557e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell */ 1567e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->next_free->prev_free = p->prev_free; 1577e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell p->prev_free->next_free = p->next_free; 1587e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 159c26f36c830cc6df1093a145eb43645f535004eb7Keith Whitwell p->next_free = 0; 160c26f36c830cc6df1093a145eb43645f535004eb7Keith Whitwell p->prev_free = 0; 161c26f36c830cc6df1093a145eb43645f535004eb7Keith Whitwell 16293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell p->reserved = reserved; 16393a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return p; 16493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell} 16593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 1661c236fd5c734b7388d7625ce8c3d4b2d6da9fcfbBrian Paul 1672b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith Whitwellstruct mem_block * 16860325331a8a76f3c783284c65b81cee471d7d64cJosé FonsecammAllocMem(struct mem_block *heap, unsigned size, unsigned align2, unsigned startSearch) 16993a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell{ 1707e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell struct mem_block *p; 17160325331a8a76f3c783284c65b81cee471d7d64cJosé Fonseca const unsigned mask = (1 << align2)-1; 17260325331a8a76f3c783284c65b81cee471d7d64cJosé Fonseca unsigned startofs = 0; 17360325331a8a76f3c783284c65b81cee471d7d64cJosé Fonseca unsigned endofs; 17493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 17578f4a695ad7140cd0148467f041e874afc655426Michel Dänzer if (!heap || !size) 17693a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return NULL; 1772b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith Whitwell 1787e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell for (p = heap->next_free; p != heap; p = p->next_free) { 1797e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell assert(p->free); 1807e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 1817e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell startofs = (p->ofs + mask) & ~mask; 1827e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell if ( startofs < startSearch ) { 1837e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell startofs = startSearch; 18493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } 1857e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell endofs = startofs+size; 1867e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell if (endofs <= (p->ofs+p->size)) 1877e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell break; 18893a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } 1897e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 1907e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell if (p == heap) 19193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return NULL; 1927e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 193c26f36c830cc6df1093a145eb43645f535004eb7Keith Whitwell assert(p->free); 19493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell p = SliceBlock(p,startofs,size,0,mask+1); 1957e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 19693a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return p; 19793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell} 19893a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 1991c236fd5c734b7388d7625ce8c3d4b2d6da9fcfbBrian Paul 2002b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith Whitwellstruct mem_block * 20160325331a8a76f3c783284c65b81cee471d7d64cJosé FonsecammFindBlock(struct mem_block *heap, unsigned start) 202005469005df6ba5f80e382d5371c6d069c27738bKeith Whitwell{ 2037e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell struct mem_block *p; 204005469005df6ba5f80e382d5371c6d069c27738bKeith Whitwell 20560ba2d88b31b4858c019b41c982ca83ab5880ddeMichal Krol for (p = heap->next; p != heap; p = p->next) { 2067e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell if (p->ofs == start) 207005469005df6ba5f80e382d5371c6d069c27738bKeith Whitwell return p; 208005469005df6ba5f80e382d5371c6d069c27738bKeith Whitwell } 209005469005df6ba5f80e382d5371c6d069c27738bKeith Whitwell 210005469005df6ba5f80e382d5371c6d069c27738bKeith Whitwell return NULL; 211005469005df6ba5f80e382d5371c6d069c27738bKeith Whitwell} 212005469005df6ba5f80e382d5371c6d069c27738bKeith Whitwell 213005469005df6ba5f80e382d5371c6d069c27738bKeith Whitwell 2149520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline int 2152b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith WhitwellJoin2Blocks(struct mem_block *p) 21693a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell{ 2171c236fd5c734b7388d7625ce8c3d4b2d6da9fcfbBrian Paul /* XXX there should be some assertions here */ 2187e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 2197e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell /* NOTE: heap->free == 0 */ 2207e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 2217e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell if (p->free && p->next->free) { 2222b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith Whitwell struct mem_block *q = p->next; 223c26f36c830cc6df1093a145eb43645f535004eb7Keith Whitwell 224c26f36c830cc6df1093a145eb43645f535004eb7Keith Whitwell assert(p->ofs + p->size == q->ofs); 22593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell p->size += q->size; 2267e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 22793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell p->next = q->next; 2287e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell q->next->prev = p; 2297e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 2307e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell q->next_free->prev_free = q->prev_free; 2317e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell q->prev_free->next_free = q->next_free; 2327e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 23332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(q); 23493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return 1; 23593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } 23693a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return 0; 23793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell} 23893a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 2391c236fd5c734b7388d7625ce8c3d4b2d6da9fcfbBrian Paulint 2402b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith WhitwellmmFreeMem(struct mem_block *b) 24193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell{ 24293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell if (!b) 24393a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return 0; 2447e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 2457e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell if (b->free) { 2467e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell fprintf(stderr, "block already free\n"); 24793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return -1; 24893a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } 2497e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell if (b->reserved) { 2507e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell fprintf(stderr, "block is reserved\n"); 25193a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return -1; 25293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } 2537e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 2547e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell b->free = 1; 2557e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell b->next_free = b->heap->next_free; 2567e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell b->prev_free = b->heap; 2577e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell b->next_free->prev_free = b; 2587e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell b->prev_free->next_free = b; 2597e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 2607e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell Join2Blocks(b); 261c26f36c830cc6df1093a145eb43645f535004eb7Keith Whitwell if (b->prev != b->heap) 2627e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell Join2Blocks(b->prev); 2637e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 26493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return 0; 26593a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell} 26693a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 26793a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 2681c236fd5c734b7388d7625ce8c3d4b2d6da9fcfbBrian Paulvoid 2692b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith WhitwellmmDestroy(struct mem_block *heap) 27093a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell{ 2712b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith Whitwell struct mem_block *p; 27293a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell 27393a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell if (!heap) 27493a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell return; 2751c236fd5c734b7388d7625ce8c3d4b2d6da9fcfbBrian Paul 2767e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell for (p = heap->next; p != heap; ) { 2772b8e66d210c333c1f9bdb4e2de079798f1c810f1Keith Whitwell struct mem_block *next = p->next; 27832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(p); 2791c236fd5c734b7388d7625ce8c3d4b2d6da9fcfbBrian Paul p = next; 28093a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell } 2817e3fa7e837aaf687996abdd8511f6bf32e2c9097Keith Whitwell 28232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(heap); 28393a458840c77b784fb74738f734ba2c5d22ca7a7Keith Whitwell} 284