Logo Search packages:      
Sourcecode: csound version File versions  Download package

memalloc.c

/*
    memalloc.c:

    Copyright (C) 1991 Barry Vercoe, John ffitch, Richard Dobson,
              (C) 2005 Istvan Varga

    This file is part of Csound.

    The Csound Library is free software; you can redistribute it
    and/or modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    Csound is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Csound; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA
*/

#include "csoundCore.h"                 /*              MEMALLOC.C      */

#if defined(BETA) && !defined(MEMDEBUG)
#define MEMDEBUG  1
#endif

#define MEMALLOC_MAGIC  0x6D426C6B

typedef struct memAllocBlock_s {
#ifdef MEMDEBUG
    int                     magic;      /* 0x6D426C6B ("mBlk")          */
    void                    *ptr;       /* pointer to allocated area    */
#endif
    struct memAllocBlock_s  *prv;       /* previous structure in chain  */
    struct memAllocBlock_s  *nxt;       /* next structure in chain      */
} memAllocBlock_t;

#define HDR_SIZE    (((int) sizeof(memAllocBlock_t) + 7) & (~7))
#define ALLOC_BYTES(n)  ((size_t) HDR_SIZE + (size_t) (n))
#define DATA_PTR(p) ((void*) ((unsigned char*) (p) + (int) HDR_SIZE))
#define HDR_PTR(p)  ((memAllocBlock_t*) ((unsigned char*) (p) - (int) HDR_SIZE))

#define MEMALLOC_DB (csound->memalloc_db)

static void memdie(CSOUND *csound, size_t nbytes)
{
    csound->ErrorMsg(csound, Str("memory allocate failure for %lu"),
                             (unsigned long) nbytes);
    csound->LongJmp(csound, CSOUND_MEMORY);
}

void *mmalloc(CSOUND *csound, size_t size)
{
    void  *p;

#ifdef MEMDEBUG
    if (size == (size_t) 0) {
      fprintf(stderr,
              " *** internal error: mmalloc() called with zero nbytes\n");
      return NULL;
    }
#endif
    /* allocate memory */
    if ((p = malloc(ALLOC_BYTES(size))) == NULL) {
      memdie(csound, size);
      return NULL;
    }
    /* link into chain */
#ifdef MEMDEBUG
    ((memAllocBlock_t*) p)->magic = MEMALLOC_MAGIC;
    ((memAllocBlock_t*) p)->ptr = DATA_PTR(p);
#endif
    ((memAllocBlock_t*) p)->prv = (memAllocBlock_t*) NULL;
    ((memAllocBlock_t*) p)->nxt = (memAllocBlock_t*) MEMALLOC_DB;
    if (MEMALLOC_DB != NULL)
      ((memAllocBlock_t*) MEMALLOC_DB)->prv = (memAllocBlock_t*) p;
    MEMALLOC_DB = (void*) p;
    /* return with data pointer */
    return DATA_PTR(p);
}

void *mcalloc(CSOUND *csound, size_t size)
{
    void  *p;

#ifdef MEMDEBUG
    if (size == (size_t) 0) {
      fprintf(stderr,
              " *** internal error: mcalloc() called with zero nbytes\n");
      return NULL;
    }
#endif
    /* allocate memory */
    if ((p = calloc(ALLOC_BYTES(size), (size_t) 1)) == NULL) {
      memdie(csound, size);
      return NULL;
    }
    /* link into chain */
#ifdef MEMDEBUG
    ((memAllocBlock_t*) p)->magic = MEMALLOC_MAGIC;
    ((memAllocBlock_t*) p)->ptr = DATA_PTR(p);
#endif
    ((memAllocBlock_t*) p)->prv = (memAllocBlock_t*) NULL;
    ((memAllocBlock_t*) p)->nxt = (memAllocBlock_t*) MEMALLOC_DB;
    if (MEMALLOC_DB != NULL)
      ((memAllocBlock_t*) MEMALLOC_DB)->prv = (memAllocBlock_t*) p;
    MEMALLOC_DB = (void*) p;
    /* return with data pointer */
    return DATA_PTR(p);
}

void mfree(CSOUND *csound, void *p)
{
    memAllocBlock_t *pp;

    if (p == NULL)
      return;
    pp = HDR_PTR(p);
#ifdef MEMDEBUG
    if (pp->magic != MEMALLOC_MAGIC || pp->ptr != p) {
      fprintf(stderr, " *** internal error: mfree() called with invalid "
                      "pointer (%p)\n", p);
      /* exit() is ugly, but this is a fatal error that can only occur */
      /* as a result of a bug */
      exit(-1);
    }
    pp->magic = 0;
#endif
    /* unlink from chain */
    if (pp->nxt != NULL)
      pp->nxt->prv = pp->prv;
    if (pp->prv != NULL)
      pp->prv->nxt = pp->nxt;
    else
      MEMALLOC_DB = (void*) pp->nxt;
    /* free memory */
    free((void*) pp);
}

void *mrealloc(CSOUND *csound, void *oldp, size_t size)
{
    memAllocBlock_t *pp;
    void            *p;

    if (oldp == NULL)
      return mmalloc(csound, size);
    if (size == (size_t) 0) {
      mfree(csound, oldp);
      return NULL;
    }
    pp = HDR_PTR(oldp);
#ifdef MEMDEBUG
    if (pp->magic != MEMALLOC_MAGIC || pp->ptr != oldp) {
      fprintf(stderr, " *** internal error: mrealloc() called with invalid "
                      "pointer (%p)\n", oldp);
      /* exit() is ugly, but this is a fatal error that can only occur */
      /* as a result of a bug */
      exit(-1);
    }
    /* mark old header as invalid */
    pp->magic = 0;
    pp->ptr = NULL;
#endif
    /* allocate memory */
    p = realloc((void*) pp, ALLOC_BYTES(size));
    if (p == NULL) {
#ifdef MEMDEBUG
      /* alloc failed, restore original header */
      pp->magic = MEMALLOC_MAGIC;
      pp->ptr = oldp;
#endif
      memdie(csound, size);
      return NULL;
    }
    /* create new header and update chain pointers */
    pp = (memAllocBlock_t*) p;
#ifdef MEMDEBUG
    pp->magic = MEMALLOC_MAGIC;
    pp->ptr = DATA_PTR(pp);
#endif
    if (pp->nxt != NULL)
      pp->nxt->prv = pp;
    if (pp->prv != NULL)
      pp->prv->nxt = pp;
    else
      MEMALLOC_DB = (void*) pp;
    /* return with data pointer */
    return DATA_PTR(pp);
}

void memRESET(CSOUND *csound)
{
    memAllocBlock_t *pp, *nxtp;

    pp = (memAllocBlock_t*) MEMALLOC_DB;
    MEMALLOC_DB = NULL;
    while (pp != NULL) {
      nxtp = pp->nxt;
#ifdef MEMDEBUG
      pp->magic = 0;
#endif
      free((void*) pp);
      pp = nxtp;
    }
}


Generated by  Doxygen 1.6.0   Back to index