Path: blob/devel/elmergrid/src/metis-5.1.0/GKlib/mcore.c
3206 views
/*!1\file2\brief Functions dealing with creating and allocating mcores34\date Started 5/30/115\author George6\author Copyright 1997-2011, Regents of the University of Minnesota7\version $Id: mcore.c 13953 2013-03-30 16:20:07Z karypis $8*/910#include <GKlib.h>111213/*************************************************************************/14/*! This function creates an mcore15*/16/*************************************************************************/17gk_mcore_t *gk_mcoreCreate(size_t coresize)18{19gk_mcore_t *mcore;2021mcore = (gk_mcore_t *)gk_malloc(sizeof(gk_mcore_t), "gk_mcoreCreate: mcore");22memset(mcore, 0, sizeof(gk_mcore_t));2324mcore->coresize = coresize;25mcore->corecpos = 0;2627mcore->core = (coresize == 0 ? NULL : gk_malloc(mcore->coresize, "gk_mcoreCreate: core"));2829/* allocate the memory for keeping track of malloc ops */30mcore->nmops = 2048;31mcore->cmop = 0;32mcore->mops = (gk_mop_t *)gk_malloc(mcore->nmops*sizeof(gk_mop_t), "gk_mcoreCreate: mcore->mops");3334return mcore;35}363738/*************************************************************************/39/*! This function creates an mcore. This version is used for gkmcore.40*/41/*************************************************************************/42gk_mcore_t *gk_gkmcoreCreate()43{44gk_mcore_t *mcore;4546if ((mcore = (gk_mcore_t *)malloc(sizeof(gk_mcore_t))) == NULL)47return NULL;48memset(mcore, 0, sizeof(gk_mcore_t));4950/* allocate the memory for keeping track of malloc ops */51mcore->nmops = 2048;52mcore->cmop = 0;53if ((mcore->mops = (gk_mop_t *)malloc(mcore->nmops*sizeof(gk_mop_t))) == NULL) {54free(mcore);55return NULL;56}5758return mcore;59}606162/*************************************************************************/63/*! This function destroys an mcore.64*/65/*************************************************************************/66void gk_mcoreDestroy(gk_mcore_t **r_mcore, int showstats)67{68gk_mcore_t *mcore = *r_mcore;6970if (mcore == NULL)71return;7273if (showstats)74printf("\n gk_mcore statistics\n"75" coresize: %12zu nmops: %12zu cmop: %6zu\n"76" num_callocs: %12zu num_hallocs: %12zu\n"77" size_callocs: %12zu size_hallocs: %12zu\n"78" cur_callocs: %12zu cur_hallocs: %12zu\n"79" max_callocs: %12zu max_hallocs: %12zu\n",80mcore->coresize, mcore->nmops, mcore->cmop,81mcore->num_callocs, mcore->num_hallocs,82mcore->size_callocs, mcore->size_hallocs,83mcore->cur_callocs, mcore->cur_hallocs,84mcore->max_callocs, mcore->max_hallocs);8586if (mcore->cur_callocs != 0 || mcore->cur_hallocs != 0 || mcore->cmop != 0) {87printf("***Warning: mcore memory was not fully freed when destroyed.\n"88" cur_callocs: %6zu cur_hallocs: %6zu cmop: %6zu\n",89mcore->cur_callocs, mcore->cur_hallocs, mcore->cmop);90}9192gk_free((void **)&mcore->core, &mcore->mops, &mcore, LTERM);9394*r_mcore = NULL;95}969798/*************************************************************************/99/*! This function destroys an mcore. This version is for gkmcore.100*/101/*************************************************************************/102void gk_gkmcoreDestroy(gk_mcore_t **r_mcore, int showstats)103{104gk_mcore_t *mcore = *r_mcore;105106if (mcore == NULL)107return;108109if (showstats)110printf("\n gk_mcore statistics\n"111" nmops: %12zu cmop: %6zu\n"112" num_hallocs: %12zu\n"113" size_hallocs: %12zu\n"114" cur_hallocs: %12zu\n"115" max_hallocs: %12zu\n",116mcore->nmops, mcore->cmop,117mcore->num_hallocs,118mcore->size_hallocs,119mcore->cur_hallocs,120mcore->max_hallocs);121122if (mcore->cur_hallocs != 0 || mcore->cmop != 0) {123printf("***Warning: mcore memory was not fully freed when destroyed.\n"124" cur_hallocs: %6zu cmop: %6zu\n",125mcore->cur_hallocs, mcore->cmop);126}127128free(mcore->mops);129free(mcore);130131*r_mcore = NULL;132}133134135/*************************************************************************/136/*! This function allocate space from the core/heap137*/138/*************************************************************************/139void *gk_mcoreMalloc(gk_mcore_t *mcore, size_t nbytes)140{141void *ptr;142143/* pad to make pointers 8-byte aligned */144nbytes += (nbytes%8 == 0 ? 0 : 8 - nbytes%8);145146if (mcore->corecpos + nbytes < mcore->coresize) {147/* service this request from the core */148ptr = ((char *)mcore->core)+mcore->corecpos;149mcore->corecpos += nbytes;150151gk_mcoreAdd(mcore, GK_MOPT_CORE, nbytes, ptr);152}153else {154/* service this request from the heap */155ptr = gk_malloc(nbytes, "gk_mcoremalloc: ptr");156157gk_mcoreAdd(mcore, GK_MOPT_HEAP, nbytes, ptr);158}159160/*161printf("MCMALLOC: %zu %d %8zu\n", mcore->cmop-1,162mcore->mops[mcore->cmop-1].type, mcore->mops[mcore->cmop-1].nbytes);163*/164165return ptr;166}167168169/*************************************************************************/170/*! This function sets a marker in the stack of malloc ops to be used171subsequently for freeing purposes172*/173/*************************************************************************/174void gk_mcorePush(gk_mcore_t *mcore)175{176gk_mcoreAdd(mcore, GK_MOPT_MARK, 0, NULL);177/* printf("MCPPUSH: %zu\n", mcore->cmop-1); */178}179180181/*************************************************************************/182/*! This function sets a marker in the stack of malloc ops to be used183subsequently for freeing purposes. This is the gkmcore version.184*/185/*************************************************************************/186void gk_gkmcorePush(gk_mcore_t *mcore)187{188gk_gkmcoreAdd(mcore, GK_MOPT_MARK, 0, NULL);189/* printf("MCPPUSH: %zu\n", mcore->cmop-1); */190}191192193/*************************************************************************/194/*! This function frees all mops since the last push195*/196/*************************************************************************/197void gk_mcorePop(gk_mcore_t *mcore)198{199while (mcore->cmop > 0) {200mcore->cmop--;201switch (mcore->mops[mcore->cmop].type) {202case GK_MOPT_MARK: /* push marker */203goto DONE;204break;205206case GK_MOPT_CORE: /* core free */207if (mcore->corecpos < mcore->mops[mcore->cmop].nbytes)208errexit("Internal Error: wspace's core is about to be over-freed [%zu, %zu, %zd]\n",209mcore->coresize, mcore->corecpos, mcore->mops[mcore->cmop].nbytes);210211mcore->corecpos -= mcore->mops[mcore->cmop].nbytes;212mcore->cur_callocs -= mcore->mops[mcore->cmop].nbytes;213break;214215case GK_MOPT_HEAP: /* heap free */216gk_free((void **)&mcore->mops[mcore->cmop].ptr, LTERM);217mcore->cur_hallocs -= mcore->mops[mcore->cmop].nbytes;218break;219220default:221gk_errexit(SIGMEM, "Unknown mop type of %d\n", mcore->mops[mcore->cmop].type);222}223}224225DONE:226;227/*printf("MCPPOP: %zu\n", mcore->cmop); */228}229230231/*************************************************************************/232/*! This function frees all mops since the last push. This version is233for poping the gkmcore and it uses free instead of gk_free.234*/235/*************************************************************************/236void gk_gkmcorePop(gk_mcore_t *mcore)237{238while (mcore->cmop > 0) {239mcore->cmop--;240switch (mcore->mops[mcore->cmop].type) {241case GK_MOPT_MARK: /* push marker */242goto DONE;243break;244245case GK_MOPT_HEAP: /* heap free */246free(mcore->mops[mcore->cmop].ptr);247mcore->cur_hallocs -= mcore->mops[mcore->cmop].nbytes;248break;249250default:251gk_errexit(SIGMEM, "Unknown mop type of %d\n", mcore->mops[mcore->cmop].type);252}253}254255DONE:256;257}258259260/*************************************************************************/261/*! Adds a memory allocation at the end of the list.262*/263/*************************************************************************/264void gk_mcoreAdd(gk_mcore_t *mcore, int type, size_t nbytes, void *ptr)265{266if (mcore->cmop == mcore->nmops) {267mcore->nmops *= 2;268mcore->mops = realloc(mcore->mops, mcore->nmops*sizeof(gk_mop_t));269if (mcore->mops == NULL)270gk_errexit(SIGMEM, "***Memory allocation for gkmcore failed.\n");271}272273mcore->mops[mcore->cmop].type = type;274mcore->mops[mcore->cmop].nbytes = nbytes;275mcore->mops[mcore->cmop].ptr = ptr;276mcore->cmop++;277278switch (type) {279case GK_MOPT_MARK:280break;281282case GK_MOPT_CORE:283mcore->num_callocs++;284mcore->size_callocs += nbytes;285mcore->cur_callocs += nbytes;286if (mcore->max_callocs < mcore->cur_callocs)287mcore->max_callocs = mcore->cur_callocs;288break;289290case GK_MOPT_HEAP:291mcore->num_hallocs++;292mcore->size_hallocs += nbytes;293mcore->cur_hallocs += nbytes;294if (mcore->max_hallocs < mcore->cur_hallocs)295mcore->max_hallocs = mcore->cur_hallocs;296break;297default:298gk_errexit(SIGMEM, "Incorrect mcore type operation.\n");299}300}301302303/*************************************************************************/304/*! Adds a memory allocation at the end of the list. This is the gkmcore305version.306*/307/*************************************************************************/308void gk_gkmcoreAdd(gk_mcore_t *mcore, int type, size_t nbytes, void *ptr)309{310if (mcore->cmop == mcore->nmops) {311mcore->nmops *= 2;312mcore->mops = realloc(mcore->mops, mcore->nmops*sizeof(gk_mop_t));313if (mcore->mops == NULL)314gk_errexit(SIGMEM, "***Memory allocation for gkmcore failed.\n");315}316317mcore->mops[mcore->cmop].type = type;318mcore->mops[mcore->cmop].nbytes = nbytes;319mcore->mops[mcore->cmop].ptr = ptr;320mcore->cmop++;321322switch (type) {323case GK_MOPT_MARK:324break;325326case GK_MOPT_HEAP:327mcore->num_hallocs++;328mcore->size_hallocs += nbytes;329mcore->cur_hallocs += nbytes;330if (mcore->max_hallocs < mcore->cur_hallocs)331mcore->max_hallocs = mcore->cur_hallocs;332break;333default:334gk_errexit(SIGMEM, "Incorrect mcore type operation.\n");335}336}337338339/*************************************************************************/340/*! This function deletes the mop associated with the supplied pointer.341The mop has to be a heap allocation, otherwise it fails violently.342*/343/*************************************************************************/344void gk_mcoreDel(gk_mcore_t *mcore, void *ptr)345{346int i;347348for (i=mcore->cmop-1; i>=0; i--) {349if (mcore->mops[i].type == GK_MOPT_MARK)350gk_errexit(SIGMEM, "Could not find pointer %p in mcore\n", ptr);351352if (mcore->mops[i].ptr == ptr) {353if (mcore->mops[i].type != GK_MOPT_HEAP)354gk_errexit(SIGMEM, "Trying to delete a non-HEAP mop.\n");355356mcore->cur_hallocs -= mcore->mops[i].nbytes;357mcore->mops[i] = mcore->mops[--mcore->cmop];358return;359}360}361362gk_errexit(SIGMEM, "mcoreDel should never have been here!\n");363}364365366/*************************************************************************/367/*! This function deletes the mop associated with the supplied pointer.368The mop has to be a heap allocation, otherwise it fails violently.369This is the gkmcore version.370*/371/*************************************************************************/372void gk_gkmcoreDel(gk_mcore_t *mcore, void *ptr)373{374int i;375376for (i=mcore->cmop-1; i>=0; i--) {377if (mcore->mops[i].type == GK_MOPT_MARK)378gk_errexit(SIGMEM, "Could not find pointer %p in mcore\n", ptr);379380if (mcore->mops[i].ptr == ptr) {381if (mcore->mops[i].type != GK_MOPT_HEAP)382gk_errexit(SIGMEM, "Trying to delete a non-HEAP mop.\n");383384mcore->cur_hallocs -= mcore->mops[i].nbytes;385mcore->mops[i] = mcore->mops[--mcore->cmop];386return;387}388}389390gk_errexit(SIGMEM, "gkmcoreDel should never have been here!\n");391}392393394395