remove the XFree86 ID line
[mesa.git] / src / mesa / drivers / dri / common / mm.c
1 /*
2 * GLX Hardware Device Driver common code
3 * Copyright (C) 1999 Wittawat Yamwong
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
21 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24 /* $XFree86: xc/lib/GL/mesa/src/drv/common/mm.c,v 1.4 2002/10/30 12:51:27 alanh Exp $ */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28
29 #include "mm.h"
30
31
32 void mmDumpMemInfo( memHeap_t *heap )
33 {
34 TMemBlock *p;
35
36 fprintf(stderr, "Memory heap %p:\n", (void *)heap);
37 if (heap == 0) {
38 fprintf(stderr, " heap == 0\n");
39 } else {
40 p = (TMemBlock *)heap;
41 while (p) {
42 fprintf(stderr, " Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
43 p->free ? '.':'U',
44 p->reserved ? 'R':'.');
45 p = p->next;
46 }
47 }
48 fprintf(stderr, "End of memory blocks\n");
49 }
50
51 memHeap_t *mmInit(int ofs,
52 int size)
53 {
54 PMemBlock blocks;
55
56 if (size <= 0) {
57 return NULL;
58 }
59 blocks = (TMemBlock *) calloc(1,sizeof(TMemBlock));
60 if (blocks) {
61 blocks->ofs = ofs;
62 blocks->size = size;
63 blocks->free = 1;
64 return (memHeap_t *)blocks;
65 } else
66 return NULL;
67 }
68
69
70 static TMemBlock* SliceBlock(TMemBlock *p,
71 int startofs, int size,
72 int reserved, int alignment)
73 {
74 TMemBlock *newblock;
75
76 /* break left */
77 if (startofs > p->ofs) {
78 newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock));
79 if (!newblock)
80 return NULL;
81 newblock->ofs = startofs;
82 newblock->size = p->size - (startofs - p->ofs);
83 newblock->free = 1;
84 newblock->next = p->next;
85 p->size -= newblock->size;
86 p->next = newblock;
87 p = newblock;
88 }
89
90 /* break right */
91 if (size < p->size) {
92 newblock = (TMemBlock*) calloc(1,sizeof(TMemBlock));
93 if (!newblock)
94 return NULL;
95 newblock->ofs = startofs + size;
96 newblock->size = p->size - size;
97 newblock->free = 1;
98 newblock->next = p->next;
99 p->size = size;
100 p->next = newblock;
101 }
102
103 /* p = middle block */
104 p->align = alignment;
105 p->free = 0;
106 p->reserved = reserved;
107 return p;
108 }
109
110 PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
111 {
112 int mask,startofs,endofs;
113 TMemBlock *p;
114
115 if (!heap || align2 < 0 || size <= 0)
116 return NULL;
117 mask = (1 << align2)-1;
118 startofs = 0;
119 p = (TMemBlock *)heap;
120 while (p) {
121 if ((p)->free) {
122 startofs = (p->ofs + mask) & ~mask;
123 if ( startofs < startSearch ) {
124 startofs = startSearch;
125 }
126 endofs = startofs+size;
127 if (endofs <= (p->ofs+p->size))
128 break;
129 }
130 p = p->next;
131 }
132 if (!p)
133 return NULL;
134 p = SliceBlock(p,startofs,size,0,mask+1);
135 p->heap = heap;
136 return p;
137 }
138
139 static __inline__ int Join2Blocks(TMemBlock *p)
140 {
141 if (p->free && p->next && p->next->free) {
142 TMemBlock *q = p->next;
143 p->size += q->size;
144 p->next = q->next;
145 free(q);
146 return 1;
147 }
148 return 0;
149 }
150
151 int mmFreeMem(PMemBlock b)
152 {
153 TMemBlock *p,*prev;
154
155 if (!b)
156 return 0;
157 if (!b->heap) {
158 fprintf(stderr, "no heap\n");
159 return -1;
160 }
161 p = b->heap;
162 prev = NULL;
163 while (p && p != b) {
164 prev = p;
165 p = p->next;
166 }
167 if (!p || p->free || p->reserved) {
168 if (!p)
169 fprintf(stderr, "block not found in heap\n");
170 else if (p->free)
171 fprintf(stderr, "block already free\n");
172 else
173 fprintf(stderr, "block is reserved\n");
174 return -1;
175 }
176 p->free = 1;
177 Join2Blocks(p);
178 if (prev)
179 Join2Blocks(prev);
180 return 0;
181 }
182
183
184 void mmDestroy(memHeap_t *heap)
185 {
186 TMemBlock *p,*q;
187
188 if (!heap)
189 return;
190 p = (TMemBlock *)heap;
191 while (p) {
192 q = p->next;
193 free(p);
194 p = q;
195 }
196 }