ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mm.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.