/* (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 Stijn van Dongen * (C) Copyright 2006, 2007 Stijn van Dongen * * This file is part of tingea. You can redistribute and/or modify tingea * under the terms of the GNU General Public License; either version 3 of the * License or (at your option) any later version. You should have received a * copy of the GPL along with tingea, in the file COPYING. */ /* include include include include */ #include #include #include "alloc.h" #include "err.h" static dim mcx_alloc_maxchunksize = 1048576; static long mcx_alloc_maxtimes = -1; static mcxbool mcx_alloc_limit = FALSE; void mcxAllocLimits ( long maxchunksize , long maxtimes ) { if (maxchunksize > 0) mcx_alloc_maxchunksize = maxchunksize ; if (maxtimes > 0) mcx_alloc_maxtimes = maxtimes ; mcx_alloc_limit = TRUE; ; } void* mcxRealloc ( void* object , dim new_size , mcxOnFail ON_FAIL ) { void* mblock = NULL ; mcxstatus status = STATUS_OK ; if (!new_size) { if (object) mcxFree(object) ; } else { if ( mcx_alloc_limit && (!mcx_alloc_maxtimes-- || new_size > mcx_alloc_maxchunksize) ) mblock = NULL ; else mblock = object ? realloc(object, new_size) : malloc(new_size) ; } if (new_size && (!mblock)) mcxMemDenied(stderr, "mcxRealloc", "byte", new_size) , status = 1 ; if (status) { if (ON_FAIL == SLEEP_ON_FAIL) { mcxTell("mcxRealloc", "pid %ld, entering sleep mode", (long) getpid()) ; while(1) sleep(1000) ; } if (ON_FAIL == EXIT_ON_FAIL) { mcxTell("mcxRealloc", "going down") ; exit(1) ; } } return mblock ; } void mcxNFree ( void* base , dim n_elem , dim elem_size , void (*obRelease) (void *) ) { if (n_elem && obRelease) { char *ob = base ; while (n_elem-- > 0) obRelease(ob) , ob += elem_size ; } mcxFree(base) ; } void* mcxNAlloc ( dim n_elem , dim elem_size , void* (*obInit) (void *) , mcxOnFail ON_FAIL ) { return mcxNRealloc(NULL, n_elem, 0, elem_size, obInit, ON_FAIL) ; } void* mcxNRealloc ( void* mem , dim n_elem , dim n_elem_prev , dim elem_size , void* (*obInit) (void *) , mcxOnFail ON_FAIL ) { char* ob ; mem = mcxRealloc(mem, n_elem * elem_size, ON_FAIL) ; if (!mem) return NULL ; if (obInit && n_elem > n_elem_prev) { ob = ((char*) mem) + (elem_size * n_elem_prev) ; while (n_elem-- > n_elem_prev) /* careful with unsignedness */ { obInit(ob) ; ob += elem_size ; } } return mem ; } void mcxMemDenied ( FILE* channel , const char* requestee , const char* unittype , dim n ) { mcxErrf ( channel , requestee , "memory shortage: could not alloc [%lu] instances of [%s]" , (ulong) n , unittype ) ; } void mcxFree ( void* object ) { if (object) free(object) ; } void* mcxAlloc ( dim size , mcxOnFail ON_FAIL ) { return mcxRealloc(NULL, size, ON_FAIL) ; }