| /* |
| ** mem.c |
| ** TecCGraf - PUC-Rio |
| */ |
| |
| char *rcs_luamem = "$Id: luamem.c,v 1.15 1997/03/31 14:17:09 roberto Exp roberto $"; |
| |
| #include <stdlib.h> |
| |
| #include "luamem.h" |
| #include "lua.h" |
| |
| |
| #define DEBUG 0 |
| |
| #if !DEBUG |
| |
| void luaI_free (void *block) |
| { |
| if (block) |
| { |
| *((char *)block) = -1; /* to catch errors */ |
| free(block); |
| } |
| } |
| |
| |
| void *luaI_realloc (void *oldblock, unsigned long size) |
| { |
| void *block; |
| size_t s = (size_t)size; |
| if (s != size) |
| lua_error("Allocation Error: Block too big"); |
| block = oldblock ? realloc(oldblock, s) : malloc(s); |
| if (block == NULL) |
| lua_error(memEM); |
| return block; |
| } |
| |
| |
| int luaI_growvector (void **block, unsigned long nelems, int size, |
| char *errormsg, unsigned long limit) |
| { |
| if (nelems >= limit) |
| lua_error(errormsg); |
| nelems = (nelems == 0) ? 20 : nelems*2; |
| if (nelems > limit) |
| nelems = limit; |
| *block = luaI_realloc(*block, nelems*size); |
| return (int)nelems; |
| } |
| |
| |
| void* luaI_buffer (unsigned long size) |
| { |
| static unsigned long buffsize = 0; |
| static char* buffer = NULL; |
| if (size > buffsize) |
| buffer = luaI_realloc(buffer, buffsize=size); |
| return buffer; |
| } |
| |
| #else |
| /* DEBUG */ |
| |
| #include <stdio.h> |
| |
| # define assert(ex) {if (!(ex)){(void)fprintf(stderr, \ |
| "Assertion failed: file \"%s\", line %d\n", __FILE__, __LINE__);exit(1);}} |
| |
| #define MARK 55 |
| |
| static unsigned long numblocks = 0; |
| static unsigned long totalmem = 0; |
| |
| |
| static void message (void) |
| { |
| #define inrange(x,y) ((x) < (((y)*3)/2) && (x) > (((y)*2)/3)) |
| static int count = 0; |
| static unsigned long lastnumblocks = 0; |
| static unsigned long lasttotalmem = 0; |
| if (!inrange(numblocks, lastnumblocks) || !inrange(totalmem, lasttotalmem) |
| || count++ >= 5000) |
| { |
| fprintf(stderr,"blocks = %lu mem = %luK\n", numblocks, totalmem/1000); |
| count = 0; |
| lastnumblocks = numblocks; |
| lasttotalmem = totalmem; |
| } |
| } |
| |
| |
| void luaI_free (void *block) |
| { |
| if (block) |
| { |
| unsigned long *b = (unsigned long *)block - 1; |
| unsigned long size = *b; |
| assert(*(((char *)b)+size+sizeof(unsigned long)) == MARK); |
| numblocks--; |
| totalmem -= size; |
| free(b); |
| message(); |
| } |
| } |
| |
| |
| void *luaI_realloc (void *oldblock, unsigned long size) |
| { |
| unsigned long *block; |
| unsigned long realsize = sizeof(unsigned long)+size+sizeof(char); |
| if (realsize != (size_t)realsize) |
| lua_error("Allocation Error: Block too big"); |
| if (oldblock) |
| { |
| unsigned long *b = (unsigned long *)oldblock - 1; |
| unsigned long oldsize = *b; |
| assert(*(((char *)b)+oldsize+sizeof(unsigned long)) == MARK); |
| totalmem -= oldsize; |
| numblocks--; |
| block = (unsigned long *)realloc(b, realsize); |
| } |
| else |
| block = (unsigned long *)malloc(realsize); |
| if (block == NULL) |
| lua_error("not enough memory"); |
| totalmem += size; |
| numblocks++; |
| *block = size; |
| *(((char *)block)+size+sizeof(unsigned long)) = MARK; |
| message(); |
| return block+1; |
| } |
| |
| |
| int luaI_growvector (void **block, unsigned long nelems, int size, |
| char *errormsg, unsigned long limit) |
| { |
| if (nelems >= limit) |
| lua_error(errormsg); |
| nelems = (nelems == 0) ? 20 : nelems*2; |
| if (nelems > limit) |
| nelems = limit; |
| *block = luaI_realloc(*block, nelems*size); |
| return (int)nelems; |
| } |
| |
| |
| void* luaI_buffer (unsigned long size) |
| { |
| static unsigned long buffsize = 0; |
| static char* buffer = NULL; |
| if (size > buffsize) |
| buffer = luaI_realloc(buffer, buffsize=size); |
| return buffer; |
| } |
| |
| #endif |