2 * GLX Hardware Device Driver common code
3 * Copyright (C) 1999 Wittawat Yamwong
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:
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
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.
33 mmDumpMemInfo(const struct mem_block
*heap
)
35 fprintf(stderr
, "Memory heap %p:\n", (void *)heap
);
37 fprintf(stderr
, " heap == 0\n");
39 const struct mem_block
*p
;
41 for(p
= heap
->next
; p
!= heap
; p
= p
->next
) {
42 fprintf(stderr
, " Offset:%08x, Size:%08x, %c%c\n",p
->ofs
,p
->size
,
44 p
->reserved
? 'R':'.');
47 fprintf(stderr
, "\nFree list:\n");
49 for(p
= heap
->next_free
; p
!= heap
; p
= p
->next_free
) {
50 fprintf(stderr
, " FREE Offset:%08x, Size:%08x, %c%c\n",p
->ofs
,p
->size
,
52 p
->reserved
? 'R':'.');
56 fprintf(stderr
, "End of memory blocks\n");
60 mmInit(unsigned ofs
, unsigned size
)
62 struct mem_block
*heap
, *block
;
67 heap
= calloc(1, sizeof(struct mem_block
));
71 block
= calloc(1, sizeof(struct mem_block
));
79 heap
->next_free
= block
;
80 heap
->prev_free
= block
;
85 block
->next_free
= heap
;
86 block
->prev_free
= heap
;
96 static struct mem_block
*
97 SliceBlock(struct mem_block
*p
,
98 unsigned startofs
, unsigned size
,
99 unsigned reserved
, unsigned alignment
)
101 struct mem_block
*newblock
;
103 /* break left [p, newblock, p->next], then p = newblock */
104 if (startofs
> p
->ofs
) {
105 newblock
= calloc(1, sizeof(struct mem_block
));
108 newblock
->ofs
= startofs
;
109 newblock
->size
= p
->size
- (startofs
- p
->ofs
);
111 newblock
->heap
= p
->heap
;
113 newblock
->next
= p
->next
;
115 p
->next
->prev
= newblock
;
118 newblock
->next_free
= p
->next_free
;
119 newblock
->prev_free
= p
;
120 p
->next_free
->prev_free
= newblock
;
121 p
->next_free
= newblock
;
123 p
->size
-= newblock
->size
;
127 /* break right, also [p, newblock, p->next] */
128 if (size
< p
->size
) {
129 newblock
= calloc(1, sizeof(struct mem_block
));
132 newblock
->ofs
= startofs
+ size
;
133 newblock
->size
= p
->size
- size
;
135 newblock
->heap
= p
->heap
;
137 newblock
->next
= p
->next
;
139 p
->next
->prev
= newblock
;
142 newblock
->next_free
= p
->next_free
;
143 newblock
->prev_free
= p
;
144 p
->next_free
->prev_free
= newblock
;
145 p
->next_free
= newblock
;
150 /* p = middle block */
153 /* Remove p from the free list:
155 p
->next_free
->prev_free
= p
->prev_free
;
156 p
->prev_free
->next_free
= p
->next_free
;
161 p
->reserved
= reserved
;
167 mmAllocMem(struct mem_block
*heap
, unsigned size
, unsigned align2
, unsigned startSearch
)
170 const unsigned mask
= (1 << align2
)-1;
171 unsigned startofs
= 0;
177 for (p
= heap
->next_free
; p
!= heap
; p
= p
->next_free
) {
180 startofs
= (p
->ofs
+ mask
) & ~mask
;
181 if ( startofs
< startSearch
) {
182 startofs
= startSearch
;
184 endofs
= startofs
+size
;
185 if (endofs
<= (p
->ofs
+p
->size
))
193 p
= SliceBlock(p
,startofs
,size
,0,mask
+1);
200 mmFindBlock(struct mem_block
*heap
, unsigned start
)
204 for (p
= heap
->next
; p
!= heap
; p
= p
->next
) {
214 Join2Blocks(struct mem_block
*p
)
216 /* XXX there should be some assertions here */
218 /* NOTE: heap->free == 0 */
220 if (p
->free
&& p
->next
->free
) {
221 struct mem_block
*q
= p
->next
;
223 assert(p
->ofs
+ p
->size
== q
->ofs
);
229 q
->next_free
->prev_free
= q
->prev_free
;
230 q
->prev_free
->next_free
= q
->next_free
;
239 mmFreeMem(struct mem_block
*b
)
245 fprintf(stderr
, "block already free\n");
249 fprintf(stderr
, "block is reserved\n");
254 b
->next_free
= b
->heap
->next_free
;
255 b
->prev_free
= b
->heap
;
256 b
->next_free
->prev_free
= b
;
257 b
->prev_free
->next_free
= b
;
260 if (b
->prev
!= b
->heap
)
261 Join2Blocks(b
->prev
);
268 mmDestroy(struct mem_block
*heap
)
275 for (p
= heap
->next
; p
!= heap
; ) {
276 struct mem_block
*next
= p
->next
;