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