Remove the many aliases for 'struct mem_block' in mm.h
[mesa.git] / src / mesa / main / 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
25 #include "mm.h"
26
27
28 void
29 mmDumpMemInfo(const struct mem_block *heap)
30 {
31 const struct mem_block *p;
32
33 fprintf(stderr, "Memory heap %p:\n", (void *)heap);
34 if (heap == 0) {
35 fprintf(stderr, " heap == 0\n");
36 } else {
37 p = (struct mem_block *)heap;
38 while (p) {
39 fprintf(stderr, " Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
40 p->free ? '.':'U',
41 p->reserved ? 'R':'.');
42 p = p->next;
43 }
44 }
45 fprintf(stderr, "End of memory blocks\n");
46 }
47
48 struct mem_block *
49 mmInit(int ofs, int size)
50 {
51 struct mem_block *blocks;
52
53 if (size <= 0) {
54 return NULL;
55 }
56 blocks = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block));
57 if (blocks) {
58 blocks->ofs = ofs;
59 blocks->size = size;
60 blocks->free = 1;
61 return (struct mem_block *)blocks;
62 }
63 else {
64 return NULL;
65 }
66 }
67
68
69 static struct mem_block *
70 SliceBlock(struct mem_block *p,
71 int startofs, int size,
72 int reserved, int alignment)
73 {
74 struct mem_block *newblock;
75
76 /* break left */
77 if (startofs > p->ofs) {
78 newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block));
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 = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block));
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
111 struct mem_block *
112 mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch)
113 {
114 struct mem_block *p = heap;
115 int mask = (1 << align2)-1;
116 int startofs = 0;
117 int endofs;
118
119 if (!heap || align2 < 0 || size <= 0)
120 return NULL;
121
122 while (p) {
123 if ((p)->free) {
124 startofs = (p->ofs + mask) & ~mask;
125 if ( startofs < startSearch ) {
126 startofs = startSearch;
127 }
128 endofs = startofs+size;
129 if (endofs <= (p->ofs+p->size))
130 break;
131 }
132 p = p->next;
133 }
134 if (!p)
135 return NULL;
136 p = SliceBlock(p,startofs,size,0,mask+1);
137 p->heap = heap;
138 return p;
139 }
140
141
142 struct mem_block *
143 mmFindBlock(struct mem_block *heap, int start)
144 {
145 struct mem_block *p = (struct mem_block *)heap;
146
147 while (p) {
148 if (p->ofs == start && p->free)
149 return p;
150
151 p = p->next;
152 }
153
154 return NULL;
155 }
156
157
158 static int
159 Join2Blocks(struct mem_block *p)
160 {
161 /* XXX there should be some assertions here */
162 if (p->free && p->next && p->next->free) {
163 struct mem_block *q = p->next;
164 p->size += q->size;
165 p->next = q->next;
166 _mesa_free(q);
167 return 1;
168 }
169 return 0;
170 }
171
172 int
173 mmFreeMem(struct mem_block *b)
174 {
175 struct mem_block *p,*prev;
176
177 if (!b)
178 return 0;
179 if (!b->heap) {
180 fprintf(stderr, "no heap\n");
181 return -1;
182 }
183 p = b->heap;
184 prev = NULL;
185 while (p && p != b) {
186 prev = p;
187 p = p->next;
188 }
189 if (!p || p->free || p->reserved) {
190 if (!p)
191 fprintf(stderr, "block not found in heap\n");
192 else if (p->free)
193 fprintf(stderr, "block already free\n");
194 else
195 fprintf(stderr, "block is reserved\n");
196 return -1;
197 }
198 p->free = 1;
199 Join2Blocks(p);
200 if (prev)
201 Join2Blocks(prev);
202 return 0;
203 }
204
205
206 void
207 mmDestroy(struct mem_block *heap)
208 {
209 struct mem_block *p;
210
211 if (!heap)
212 return;
213
214 p = (struct mem_block *) heap;
215 while (p) {
216 struct mem_block *next = p->next;
217 _mesa_free(p);
218 p = next;
219 }
220 }