Path: blob/devel/elmergrid/src/metis-5.1.0/GKlib/memory.c
3206 views
/*!1\file memory.c2\brief This file contains various allocation routines34The allocation routines included are for 1D and 2D arrays of the5most datatypes that GKlib support. Many of these routines are6defined with the help of the macros in gk_memory.h. These macros7can be used to define other memory allocation routines.89\date Started 4/3/200710\author George11\version\verbatim $Id: memory.c 10783 2011-09-21 23:19:56Z karypis $ \endverbatim12*/131415#include <GKlib.h>1617/* This is for the global mcore that tracks all heap allocations */18static __thread gk_mcore_t *gkmcore = NULL;192021/*************************************************************************/22/*! Define the set of memory allocation routines for each data type */23/**************************************************************************/24GK_MKALLOC(gk_c, char)25GK_MKALLOC(gk_i, int)26GK_MKALLOC(gk_i32, int32_t)27GK_MKALLOC(gk_i64, int64_t)28GK_MKALLOC(gk_z, ssize_t)29GK_MKALLOC(gk_f, float)30GK_MKALLOC(gk_d, double)31GK_MKALLOC(gk_idx, gk_idx_t)3233GK_MKALLOC(gk_ckv, gk_ckv_t)34GK_MKALLOC(gk_ikv, gk_ikv_t)35GK_MKALLOC(gk_i32kv, gk_i32kv_t)36GK_MKALLOC(gk_i64kv, gk_i64kv_t)37GK_MKALLOC(gk_zkv, gk_zkv_t)38GK_MKALLOC(gk_fkv, gk_fkv_t)39GK_MKALLOC(gk_dkv, gk_dkv_t)40GK_MKALLOC(gk_skv, gk_skv_t)41GK_MKALLOC(gk_idxkv, gk_idxkv_t)42434445464748/*************************************************************************/49/*! This function allocates a two-dimensional matrix.50*/51/*************************************************************************/52void gk_AllocMatrix(void ***r_matrix, size_t elmlen, size_t ndim1, size_t ndim2)53{54gk_idx_t i, j;55void **matrix;5657*r_matrix = NULL;5859if ((matrix = (void **)gk_malloc(ndim1*sizeof(void *), "gk_AllocMatrix: matrix")) == NULL)60return;6162for (i=0; i<ndim1; i++) {63if ((matrix[i] = (void *)gk_malloc(ndim2*elmlen, "gk_AllocMatrix: matrix[i]")) == NULL) {64for (j=0; j<i; j++)65gk_free((void **)&matrix[j], LTERM);66return;67}68}6970*r_matrix = matrix;71}727374/*************************************************************************/75/*! This function frees a two-dimensional matrix.76*/77/*************************************************************************/78void gk_FreeMatrix(void ***r_matrix, size_t ndim1, size_t ndim2)79{80gk_idx_t i;81void **matrix;8283if ((matrix = *r_matrix) == NULL)84return;8586for (i=0; i<ndim1; i++)87gk_free((void **)&matrix[i], LTERM);8889gk_free((void **)r_matrix, LTERM);9091}929394/*************************************************************************/95/*! This function initializes tracking of heap allocations.96*/97/*************************************************************************/98int gk_malloc_init()99{100if (gkmcore == NULL)101gkmcore = gk_gkmcoreCreate();102103if (gkmcore == NULL)104return 0;105106gk_gkmcorePush(gkmcore);107108return 1;109}110111112/*************************************************************************/113/*! This function frees the memory that has been allocated since the114last call to gk_malloc_init().115*/116/*************************************************************************/117void gk_malloc_cleanup(int showstats)118{119if (gkmcore != NULL) {120gk_gkmcorePop(gkmcore);121if (gkmcore->cmop == 0) {122gk_gkmcoreDestroy(&gkmcore, showstats);123gkmcore = NULL;124}125}126}127128129/*************************************************************************/130/*! This function is my wrapper around malloc that provides the following131enhancements over malloc:132* It always allocates one byte of memory, even if 0 bytes are requested.133This is to ensure that checks of returned values do not lead to NULL134due to 0 bytes requested.135* It zeros-out the memory that is allocated. This is for a quick init136of the underlying datastructures.137*/138/**************************************************************************/139void *gk_malloc(size_t nbytes, char *msg)140{141void *ptr=NULL;142143if (nbytes == 0)144nbytes++; /* Force mallocs to actually allocate some memory */145146ptr = (void *)malloc(nbytes);147148if (ptr == NULL) {149fprintf(stderr, " Current memory used: %10zu bytes\n", gk_GetCurMemoryUsed());150fprintf(stderr, " Maximum memory used: %10zu bytes\n", gk_GetMaxMemoryUsed());151gk_errexit(SIGMEM, "***Memory allocation failed for %s. Requested size: %zu bytes",152msg, nbytes);153return NULL;154}155156/* add this memory allocation */157if (gkmcore != NULL) gk_gkmcoreAdd(gkmcore, GK_MOPT_HEAP, nbytes, ptr);158159/* zero-out the allocated space */160#ifndef NDEBUG161memset(ptr, 0, nbytes);162#endif163164return ptr;165}166167168/*************************************************************************169* This function is my wrapper around realloc170**************************************************************************/171void *gk_realloc(void *oldptr, size_t nbytes, char *msg)172{173void *ptr=NULL;174175if (nbytes == 0)176nbytes++; /* Force mallocs to actually allocate some memory */177178/* remove this memory de-allocation */179if (gkmcore != NULL && oldptr != NULL) gk_gkmcoreDel(gkmcore, oldptr);180181ptr = (void *)realloc(oldptr, nbytes);182183if (ptr == NULL) {184fprintf(stderr, " Maximum memory used: %10zu bytes\n", gk_GetMaxMemoryUsed());185fprintf(stderr, " Current memory used: %10zu bytes\n", gk_GetCurMemoryUsed());186gk_errexit(SIGMEM, "***Memory realloc failed for %s. " "Requested size: %zu bytes",187msg, nbytes);188return NULL;189}190191/* add this memory allocation */192if (gkmcore != NULL) gk_gkmcoreAdd(gkmcore, GK_MOPT_HEAP, nbytes, ptr);193194return ptr;195}196197198/*************************************************************************199* This function is my wrapper around free, allows multiple pointers200**************************************************************************/201void gk_free(void **ptr1,...)202{203va_list plist;204void **ptr;205206if (*ptr1 != NULL) {207free(*ptr1);208209/* remove this memory de-allocation */210if (gkmcore != NULL) gk_gkmcoreDel(gkmcore, *ptr1);211}212*ptr1 = NULL;213214va_start(plist, ptr1);215while ((ptr = va_arg(plist, void **)) != LTERM) {216if (*ptr != NULL) {217free(*ptr);218219/* remove this memory de-allocation */220if (gkmcore != NULL) gk_gkmcoreDel(gkmcore, *ptr);221}222*ptr = NULL;223}224va_end(plist);225}226227228/*************************************************************************229* This function returns the current ammount of dynamically allocated230* memory that is used by the system231**************************************************************************/232size_t gk_GetCurMemoryUsed()233{234if (gkmcore == NULL)235return 0;236else237return gkmcore->cur_hallocs;238}239240241/*************************************************************************242* This function returns the maximum ammount of dynamically allocated243* memory that was used by the system244**************************************************************************/245size_t gk_GetMaxMemoryUsed()246{247if (gkmcore == NULL)248return 0;249else250return gkmcore->max_hallocs;251}252253254