]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
removing mem.c from this branch in preparation for 0.1
authorWolfgang (Blub) Bumiller <blub@speed.at>
Sat, 17 Nov 2012 09:35:52 +0000 (10:35 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Sat, 17 Nov 2012 09:35:52 +0000 (10:35 +0100)
mem.c [deleted file]

diff --git a/mem.c b/mem.c
deleted file mode 100644 (file)
index 5858ffd..0000000
--- a/mem.c
+++ /dev/null
@@ -1,360 +0,0 @@
-#include "gmqcc.h"
-#include <assert.h>
-/*
- * GMQCC does a lot of allocations on shortly lived objects all of which
- * call down to malloc/free internally.  The overhead involved with these
- * allocations makes GMQCC slow. To combat this, a special allocator was
- * in need.  This is an implementation of a user-space buddy allocator
- * that sits ontop of malloc/free.  I'd like to thank Lee Salzman for
- * guiding me in the right direction for designing this.
- */
-#define GMQCC_MEM_USED  0xEDCA10A1EDCA10A1
-#define GMQCC_MEM_FREE  0xEEF8EEF8EEF8EEF8
-#define GMQCC_MEM_BSL  -1
-#define GMQCC_MEM_BSR   1
-#define GMQCC_MEM_DEBUG 1
-
-/* debug info for dumping heap contents nicely */
-#define GMQCC_MEM_DEBUG_BPL 32 /* bytes per line    */
-#define GMQCC_MEM_DEBUG_BIG 8  /* bytes in group    */
-#define GMQCC_MEM_DEBUG_BSG 4  /* bytes split group */
-
-#ifdef  GMQCC_MEM_DEBUG
-#   include <stdio.h>
-#   define GMQCC_MEM_TRACE(TAG, ...)            \
-    do {                                        \
-        printf("[mem:%s]: %s ", TAG, __func__); \
-        printf(__VA_ARGS__);                    \
-        printf("\n");                           \
-    } while (0)
-#else
-#   define GMQCC_MEM_TRACE(TAG, ...)
-#endif
-
-typedef unsigned long int mem_addr;
-
-static void   *mem_heap = NULL;
-static size_t  mem_look = 0;  /* lookup table offset */
-static size_t  mem_size = 0;  /* heap size           */
-
-/* read or write to heap */
-#define GMQCC_MEM_WRITEHEAP(OFFSET, TYPE, VALUE)                \
-    do {                                                        \
-        TYPE *T = (TYPE*)((unsigned char*)mem_heap + (OFFSET)); \
-        *T = VALUE;                                             \
-    } while (0)
-#define GMQCC_MEM_READHEAP(OFFSET, TYPE)  ((TYPE)*((TYPE *)(((unsigned char*)mem_heap + (OFFSET)))))
-
-/* read of write first block to heap */
-#define GMQCC_MEM_WRITEFBA(SIZE, ADDR) GMQCC_MEM_WRITEHEAP(mem_look + (SIZE) * sizeof(mem_addr), mem_addr, (ADDR))
-#define GMQCC_MEM_READFBA(SIZE)        GMQCC_MEM_READHEAP (mem_look + (SIZE) * sizeof(mem_addr), mem_addr)
-
-/* read and write block sizes from heap */
-#define GMQCC_MEM_WRITEBS(ADDR, SIZE) GMQCC_MEM_WRITEHEAP(ADDR, mem_addr, (SIZE))
-#define GMQCC_MEM_READBS(ADDR)        GMQCC_MEM_READHEAP (ADDR, mem_addr);
-    
-/*
- * Getting address of previous/following siblings, as well as
- * setting address of previous/following siblings.
- */
-#define GMQCC_MEM_GETADDROFPS(ADDR)   GMQCC_MEM_READHEAP ((ADDR) + 2 * sizeof(mem_addr), mem_addr)
-#define GMQCC_MEM_GETADDROFFS(ADDR)   GMQCC_MEM_READHEAP ((ADDR) + 3 * sizeof(mem_addr), mem_addr)
-#define GMQCC_MEM_SETADDROFPS(ADDR,V) GMQCC_MEM_WRITEHEAP((ADDR) + 2 * sizeof(mem_addr), mem_addr, V)
-#define GMQCC_MEM_SETADDROFFS(ADDR,V) GMQCC_MEM_WRITEHEAP((ADDR) + 3 * sizeof(mem_addr), mem_addr, V)
-
-/* Marking blocks as used or free */
-#define GMQCC_MEM_MARKUSED(ADDR) GMQCC_MEM_WRITEHEAP((ADDR) + 1 * sizeof(mem_addr), mem_addr, GMQCC_MEM_USED)
-#define GMQCC_MEM_MARKFREE(ADDR) GMQCC_MEM_WRITEHEAP((ADDR) + 1 * sizeof(mem_addr), mem_addr, GMQCC_MEM_FREE)
-
-/* Has block? */
-#define GMQCC_MEM_HASBLOCK(SIZE) (GMQCC_MEM_READFBA(SIZE) != 0)
-
-/* Block free? */
-#define GMQCC_MEM_BLOCKFREE(ADDR) ((GMQCC_MEM_READHEAP((ADDR) + 1 * sizeof(mem_addr), mem_addr)) == GMQCC_MEM_FREE)
-
-/*
- * Must be first since it's used internally, but also should be exposed
- * to the outside, statics exist after this.
- */
-void mem_dump() {
-    size_t         addr = 0;
-    unsigned char *ptr  = (unsigned char*)mem_heap;
-    
-    while (addr < mem_size) {
-        size_t offset = 0;
-        printf("% 8X:  ", addr);
-        while (offset < GMQCC_MEM_DEBUG_BPL) {
-            if (addr + offset >= mem_size)
-                break;
-                
-            ptr    ++;
-            offset ++;
-            
-            printf (
-                !(offset%GMQCC_MEM_DEBUG_BSG) && 
-                 (offset%GMQCC_MEM_DEBUG_BIG) ? "%02X  "   :
-                !(offset%GMQCC_MEM_DEBUG_BIG) ? "%02X    " : "%02X ",
-                *ptr
-            );
-        }
-        printf("\n");
-        addr += GMQCC_MEM_DEBUG_BPL;
-    }
-}
-
-static void mem_init_table(size_t size) {
-    size_t i;
-    GMQCC_MEM_TRACE("flow", "(%lu)", size);
-    
-    mem_look = 8 * ((mem_addr)1 << (size - 1)) + sizeof(mem_addr);
-    
-    GMQCC_MEM_WRITEHEAP(0,        mem_addr, mem_look);
-    GMQCC_MEM_WRITEHEAP(mem_look, mem_addr, size);
-    
-    /* write pointers to first free bock of said size */
-    for (i = 1; i < size; i++)
-        GMQCC_MEM_WRITEHEAP(mem_look + sizeof(mem_addr) * i, mem_addr, 0);
-        
-    GMQCC_MEM_WRITEHEAP(mem_look + sizeof(mem_addr) * size, mem_addr, sizeof(mem_addr));
-    GMQCC_MEM_WRITEHEAP(sizeof(mem_addr), mem_addr, size);
-    GMQCC_MEM_MARKFREE (sizeof(mem_addr) * 2);
-    GMQCC_MEM_WRITEHEAP(sizeof(mem_addr) * 3, mem_addr, 0);
-    GMQCC_MEM_WRITEHEAP(sizeof(mem_addr) * 4, mem_addr, 0);
-}
-
-/* get needed block size */
-static size_t mem_getnbs(const size_t need) {
-    size_t b = 8;
-    size_t s = 1;
-    
-    while (need > b) {
-        b *= 2;
-        s ++;
-    }
-    
-    return s;
-}
-
-static void mem_removeblock(mem_addr a, size_t size) {
-    mem_addr p = GMQCC_MEM_GETADDROFPS(a);
-    mem_addr n = GMQCC_MEM_GETADDROFFS(a);
-    
-    GMQCC_MEM_TRACE("flow", "(%lu, %lu)", a, size);
-    
-    GMQCC_MEM_SETADDROFPS(a, ~((mem_addr)0));
-    GMQCC_MEM_SETADDROFFS(a, ~((mem_addr)0));
-    
-    /* handle singles in list */
-    if ((p == 0) && (n == 0)) {
-        GMQCC_MEM_WRITEFBA(size, 0);
-        return;
-    }
-    
-    /* first in list has different sibling semantics */
-    if (p == 0) {
-        GMQCC_MEM_WRITEFBA   (size, n);
-        GMQCC_MEM_SETADDROFPS(n, 0);
-        return;
-    }
-    
-    /* last item also has special meaning :) */
-    if (n == 0) {
-        GMQCC_MEM_SETADDROFFS(p, 0);
-        return;
-    }
-    
-    /* middle of list */
-    GMQCC_MEM_SETADDROFPS(n, p);
-    GMQCC_MEM_SETADDROFFS(p, n);
-}
-
-static int mem_createblock(const size_t size) {
-    mem_addr parent;
-    int      test;
-    
-    GMQCC_MEM_TRACE("flow", "(%lu)", size);
-    if (GMQCC_MEM_HASBLOCK(size))
-        return 0;
-        
-    if (size > GMQCC_MEM_READHEAP(mem_look, mem_addr))
-        abort();
-
-    /* recrusive ... */
-    test = mem_createblock(size + 1);
-    if (test != 0)
-        return test;
-        
-    /* safe splits assured */
-    parent = GMQCC_MEM_READFBA(size + 1);
-    mem_removeblock(parent, size + 1);
-    
-    /* split it */
-    GMQCC_MEM_WRITEFBA(size, parent);
-    {
-        /* find center and split */
-        mem_addr block = parent + 8 * ((mem_addr)1 << (size - 1));
-        mem_addr left  = parent;
-        mem_addr right = block;
-        
-        GMQCC_MEM_TRACE(
-            "dump",
-            "left: %lu right: %lu parent: %lu",
-            left, right, parent
-        );
-        
-        /* left half  */
-        GMQCC_MEM_WRITEHEAP  (left, mem_addr, size);
-        GMQCC_MEM_MARKFREE   (left);
-        GMQCC_MEM_SETADDROFPS(left, 0);
-        GMQCC_MEM_SETADDROFFS(left, right);
-        /* right half */
-        GMQCC_MEM_WRITEHEAP  (right, mem_addr, size);
-        GMQCC_MEM_MARKFREE   (right);
-        GMQCC_MEM_SETADDROFPS(right, left);
-        GMQCC_MEM_SETADDROFFS(right, 0);
-    }
-    mem_dump();
-    return 0;
-}
-
-static mem_addr mem_allocblock(const size_t size) {
-    GMQCC_MEM_TRACE("flow", "(%lu)", size);
-    int      test = mem_createblock(size);
-    mem_addr first;
-    mem_addr next;
-    
-    if (test != 0)
-        return 0;
-    
-    /* first free one */
-    first = GMQCC_MEM_READFBA    (size);
-    next  = GMQCC_MEM_GETADDROFFS(first);
-    
-    mem_removeblock(first, size);
-    
-    GMQCC_MEM_WRITEFBA(next, size);
-    GMQCC_MEM_MARKUSED(first);
-    
-    return first;
-}
-
-static int mem_getside(mem_addr addr, const size_t size) {
-    size_t start = addr - sizeof(mem_addr);
-    size_t test  = 0;
-    start /= 8;
-    test   = ((mem_addr)1 << (size));
-    
-    return ((start % test) == 0) ? GMQCC_MEM_BSL : GMQCC_MEM_BSR;
-}
-
-static mem_addr mem_getaddr(mem_addr start, const size_t size) {
-    size_t length = ((mem_addr)1 << (size - 1));
-    length *= 8;
-    
-    switch (mem_getside(start, size)) {
-        case GMQCC_MEM_BSL: return start + length;
-        case GMQCC_MEM_BSR: return start - length;
-    }
-    /* if reached blow up */
-    return (abort(), 1);
-}
-
-static void mem_addblock(mem_addr a, size_t s) {
-    mem_addr first = GMQCC_MEM_READFBA(s);
-    if (first == 0) {
-        /* only block */
-        GMQCC_MEM_WRITEFBA   (s, a);
-        GMQCC_MEM_SETADDROFPS(a, 0);
-        GMQCC_MEM_SETADDROFFS(a, 0);
-    } else {
-        /* add to front */
-        GMQCC_MEM_WRITEFBA   (s, a);
-        GMQCC_MEM_SETADDROFPS(a, 0);
-        GMQCC_MEM_SETADDROFFS(a, first);
-        GMQCC_MEM_SETADDROFPS(first, a);
-    }
-}
-
-void mem_init(size_t size) {
-    size_t alloc = size;
-    size_t count = 1;
-    size_t block = 1;
-    
-    /* blow up if too small */
-    assert (sizeof(void*) == sizeof(mem_addr));
-    
-    if (!(mem_heap = malloc(size)))
-        abort();
-    
-    memset(mem_heap, 170, size);
-    mem_size = size;
-    alloc    -= 2 * sizeof(mem_addr);
-    
-    while (alloc + sizeof(mem_addr) > 8 * block) {
-        alloc -= sizeof(mem_addr);
-        block *= 2;
-        count ++;
-    }
-    
-    /* over shot ? */
-    block /= 2;
-    count --;
-    
-    mem_init_table(count);
-}
-
-/* doesn't get any simpler :-) */
-void mem_destroy() {
-    free(mem_heap);
-    mem_heap = NULL;
-}
-
-void *mem_alloc(size_t amount) {
-    GMQCC_MEM_TRACE("flow", "(%lu)", amount);
-    size_t   need  = amount + 4 * sizeof(mem_addr);
-    size_t   size  = mem_getnbs    (need);
-    mem_addr block = mem_allocblock(size);
-    
-    GMQCC_MEM_TRACE("dump", "will allocate %lu size block", size);
-    /* standard behaviour */
-    if (block == 0)
-        return NULL;
-    GMQCC_MEM_TRACE("dump", "returning offset %lu", block);
-    return mem_heap + block + 4 * sizeof(mem_addr);
-}
-
-void mem_free(void *ptr) {
-    mem_addr start = (mem_addr)(ptr - mem_heap) - 4 * sizeof(mem_addr);
-    size_t   size  = GMQCC_MEM_READHEAP(start, mem_addr);
-    mem_addr addr  = mem_getaddr(start, size);
-    int      side  = mem_getside(start, size);
-    
-    
-    GMQCC_MEM_TRACE (
-        "dump",
-        "deallocating %s buddy (neighbour at %lu)",
-        (side == GMQCC_MEM_BSL) ? "left" : "right",
-        addr
-    );
-    GMQCC_MEM_MARKFREE(start);
-    
-    /* while free block merge */
-    while (GMQCC_MEM_BLOCKFREE(addr)) {
-        GMQCC_MEM_TRACE("dump", "merging ...");
-        mem_removeblock(addr, size);
-        
-        /* find new start */
-        start = addr < start ? addr : start;
-        size ++;
-        
-        if (size == GMQCC_MEM_READHEAP(mem_look, mem_addr))
-            break; /* blow up */
-            
-        addr = mem_getaddr(start, size);
-        GMQCC_MEM_TRACE("dump", "new block start is %lu, buddy at %lu", start, addr);
-    }
-    
-    /* add it */
-    GMQCC_MEM_WRITEBS(start, size);
-    mem_addblock     (start, size);
-}