Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmm.c
Go to the documentation of this file.
00001 /* 00002 * GLX Hardware Device Driver common code 00003 * Copyright (C) 1999 Wittawat Yamwong 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining a 00006 * copy of this software and associated documentation files (the "Software"), 00007 * to deal in the Software without restriction, including without limitation 00008 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00009 * and/or sell copies of the Software, and to permit persons to whom the 00010 * Software is furnished to do so, subject to the following conditions: 00011 * 00012 * The above copyright notice and this permission notice shall be included 00013 * in all copies or substantial portions of the Software. 00014 * 00015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00016 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00018 * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 00019 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 00020 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 00021 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00022 * 00023 */ 00024 00025 #include "mm.h" 00026 00027 00028 void 00029 mmDumpMemInfo(const struct mem_block *heap) 00030 { 00031 fprintf(stderr, "Memory heap %p:\n", (void *)heap); 00032 if (heap == 0) { 00033 fprintf(stderr, " heap == 0\n"); 00034 } else { 00035 const struct mem_block *p; 00036 00037 for(p = heap->next; p != heap; p = p->next) { 00038 fprintf(stderr, " Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, 00039 p->free ? 'F':'.', 00040 p->reserved ? 'R':'.'); 00041 } 00042 00043 fprintf(stderr, "\nFree list:\n"); 00044 00045 for(p = heap->next_free; p != heap; p = p->next_free) { 00046 fprintf(stderr, " FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, 00047 p->free ? 'F':'.', 00048 p->reserved ? 'R':'.'); 00049 } 00050 00051 } 00052 fprintf(stderr, "End of memory blocks\n"); 00053 } 00054 00055 struct mem_block * 00056 mmInit(unsigned ofs, unsigned size) 00057 { 00058 struct mem_block *heap, *block; 00059 00060 if (!size) 00061 return NULL; 00062 00063 heap = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block)); 00064 if (!heap) 00065 return NULL; 00066 00067 block = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block)); 00068 if (!block) { 00069 _mesa_free(heap); 00070 return NULL; 00071 } 00072 00073 heap->next = block; 00074 heap->prev = block; 00075 heap->next_free = block; 00076 heap->prev_free = block; 00077 00078 block->heap = heap; 00079 block->next = heap; 00080 block->prev = heap; 00081 block->next_free = heap; 00082 block->prev_free = heap; 00083 00084 block->ofs = ofs; 00085 block->size = size; 00086 block->free = 1; 00087 00088 return heap; 00089 } 00090 00091 00092 static struct mem_block * 00093 SliceBlock(struct mem_block *p, 00094 unsigned startofs, unsigned size, 00095 unsigned reserved, unsigned alignment) 00096 { 00097 struct mem_block *newblock; 00098 00099 /* break left [p, newblock, p->next], then p = newblock */ 00100 if (startofs > p->ofs) { 00101 newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block)); 00102 if (!newblock) 00103 return NULL; 00104 newblock->ofs = startofs; 00105 newblock->size = p->size - (startofs - p->ofs); 00106 newblock->free = 1; 00107 newblock->heap = p->heap; 00108 00109 newblock->next = p->next; 00110 newblock->prev = p; 00111 p->next->prev = newblock; 00112 p->next = newblock; 00113 00114 newblock->next_free = p->next_free; 00115 newblock->prev_free = p; 00116 p->next_free->prev_free = newblock; 00117 p->next_free = newblock; 00118 00119 p->size -= newblock->size; 00120 p = newblock; 00121 } 00122 00123 /* break right, also [p, newblock, p->next] */ 00124 if (size < p->size) { 00125 newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block)); 00126 if (!newblock) 00127 return NULL; 00128 newblock->ofs = startofs + size; 00129 newblock->size = p->size - size; 00130 newblock->free = 1; 00131 newblock->heap = p->heap; 00132 00133 newblock->next = p->next; 00134 newblock->prev = p; 00135 p->next->prev = newblock; 00136 p->next = newblock; 00137 00138 newblock->next_free = p->next_free; 00139 newblock->prev_free = p; 00140 p->next_free->prev_free = newblock; 00141 p->next_free = newblock; 00142 00143 p->size = size; 00144 } 00145 00146 /* p = middle block */ 00147 p->free = 0; 00148 00149 /* Remove p from the free list: 00150 */ 00151 p->next_free->prev_free = p->prev_free; 00152 p->prev_free->next_free = p->next_free; 00153 00154 p->next_free = 0; 00155 p->prev_free = 0; 00156 00157 p->reserved = reserved; 00158 return p; 00159 } 00160 00161 00162 struct mem_block * 00163 mmAllocMem(struct mem_block *heap, unsigned size, unsigned align2, unsigned startSearch) 00164 { 00165 struct mem_block *p; 00166 const unsigned mask = (1 << align2)-1; 00167 unsigned startofs = 0; 00168 unsigned endofs; 00169 00170 if (!heap || !size) 00171 return NULL; 00172 00173 for (p = heap->next_free; p != heap; p = p->next_free) { 00174 assert(p->free); 00175 00176 startofs = (p->ofs + mask) & ~mask; 00177 if ( startofs < startSearch ) { 00178 startofs = startSearch; 00179 } 00180 endofs = startofs+size; 00181 if (endofs <= (p->ofs+p->size)) 00182 break; 00183 } 00184 00185 if (p == heap) 00186 return NULL; 00187 00188 assert(p->free); 00189 p = SliceBlock(p,startofs,size,0,mask+1); 00190 00191 return p; 00192 } 00193 00194 00195 struct mem_block * 00196 mmFindBlock(struct mem_block *heap, unsigned start) 00197 { 00198 struct mem_block *p; 00199 00200 for (p = heap->next; p != heap; p = p->next) { 00201 if (p->ofs == start) 00202 return p; 00203 } 00204 00205 return NULL; 00206 } 00207 00208 00209 static INLINE int 00210 Join2Blocks(struct mem_block *p) 00211 { 00212 /* XXX there should be some assertions here */ 00213 00214 /* NOTE: heap->free == 0 */ 00215 00216 if (p->free && p->next->free) { 00217 struct mem_block *q = p->next; 00218 00219 assert(p->ofs + p->size == q->ofs); 00220 p->size += q->size; 00221 00222 p->next = q->next; 00223 q->next->prev = p; 00224 00225 q->next_free->prev_free = q->prev_free; 00226 q->prev_free->next_free = q->next_free; 00227 00228 _mesa_free(q); 00229 return 1; 00230 } 00231 return 0; 00232 } 00233 00234 int 00235 mmFreeMem(struct mem_block *b) 00236 { 00237 if (!b) 00238 return 0; 00239 00240 if (b->free) { 00241 fprintf(stderr, "block already free\n"); 00242 return -1; 00243 } 00244 if (b->reserved) { 00245 fprintf(stderr, "block is reserved\n"); 00246 return -1; 00247 } 00248 00249 b->free = 1; 00250 b->next_free = b->heap->next_free; 00251 b->prev_free = b->heap; 00252 b->next_free->prev_free = b; 00253 b->prev_free->next_free = b; 00254 00255 Join2Blocks(b); 00256 if (b->prev != b->heap) 00257 Join2Blocks(b->prev); 00258 00259 return 0; 00260 } 00261 00262 00263 void 00264 mmDestroy(struct mem_block *heap) 00265 { 00266 struct mem_block *p; 00267 00268 if (!heap) 00269 return; 00270 00271 for (p = heap->next; p != heap; ) { 00272 struct mem_block *next = p->next; 00273 _mesa_free(p); 00274 p = next; 00275 } 00276 00277 _mesa_free(heap); 00278 } Generated on Sun May 27 2012 04:19:17 for ReactOS by
1.7.6.1
|