epanet.c reset file variables to NULL so if the code is executed again without termination, the variables will be in a valid initial state. Added retrieval of EN_STARTTIME to ENgettimeparam. Added retrieval of EN_TANKVOLUME to ENgetnodevalue Added retrieval of EN_LINKQUAL to ENgetlinkvalue Fixed the check for identical filenames so it now allows for an empty (not generated) report file and outfile. Added ENgetbasedemand and ENgetdemandpattern functions input2.c Fixed some compiler warnings git-svn-id: https://epanet.svn.sourceforge.net/svnroot/epanet/BASE/trunk@424 c320cabd-cc23-0410-96d8-e60fbf53ed7f
206 lines
4.5 KiB
C
Executable File
206 lines
4.5 KiB
C
Executable File
/* mempool.c
|
|
**
|
|
** A simple fast memory allocation package.
|
|
**
|
|
** By Steve Hill in Graphics Gems III, David Kirk (ed.),
|
|
** Academic Press, Boston, MA, 1992
|
|
**
|
|
** Modified by Lew Rossman, 8/13/94.
|
|
**
|
|
** AllocInit() - create an alloc pool, returns the old pool handle
|
|
** Alloc() - allocate memory
|
|
** AllocReset() - reset the current pool
|
|
** AllocSetPool() - set the current pool
|
|
** AllocFree() - free the memory used by the current pool.
|
|
**
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#ifndef __APPLE__
|
|
#include <malloc.h>
|
|
#endif
|
|
#include "mempool.h"
|
|
|
|
/*
|
|
** ALLOC_BLOCK_SIZE - adjust this size to suit your installation - it
|
|
** should be reasonably large otherwise you will be mallocing a lot.
|
|
*/
|
|
|
|
#define ALLOC_BLOCK_SIZE 64000 /*(62*1024)*/
|
|
|
|
/*
|
|
** alloc_hdr_t - Header for each block of memory.
|
|
*/
|
|
|
|
typedef struct alloc_hdr_s
|
|
{
|
|
struct alloc_hdr_s *next; /* Next Block */
|
|
char *block, /* Start of block */
|
|
*free, /* Next free in block */
|
|
*end; /* block + block size */
|
|
} alloc_hdr_t;
|
|
|
|
/*
|
|
** alloc_root_t - Header for the whole pool.
|
|
*/
|
|
|
|
typedef struct alloc_root_s
|
|
{
|
|
alloc_hdr_t *first, /* First header in pool */
|
|
*current; /* Current header */
|
|
} alloc_root_t;
|
|
|
|
/*
|
|
** root - Pointer to the current pool.
|
|
*/
|
|
|
|
static alloc_root_t *root;
|
|
|
|
|
|
/*
|
|
** AllocHdr()
|
|
**
|
|
** Private routine to allocate a header and memory block.
|
|
*/
|
|
|
|
static alloc_hdr_t *AllocHdr(void);
|
|
|
|
static alloc_hdr_t * AllocHdr()
|
|
{
|
|
alloc_hdr_t *hdr;
|
|
char *block;
|
|
|
|
block = (char *) malloc(ALLOC_BLOCK_SIZE);
|
|
hdr = (alloc_hdr_t *) malloc(sizeof(alloc_hdr_t));
|
|
|
|
if (hdr == NULL || block == NULL) return(NULL);
|
|
hdr->block = block;
|
|
hdr->free = block;
|
|
hdr->next = NULL;
|
|
hdr->end = block + ALLOC_BLOCK_SIZE;
|
|
|
|
return(hdr);
|
|
}
|
|
|
|
|
|
/*
|
|
** AllocInit()
|
|
**
|
|
** Create a new memory pool with one block.
|
|
** Returns pointer to the new pool.
|
|
*/
|
|
|
|
DLLEXPORT alloc_handle_t * AllocInit()
|
|
{
|
|
alloc_handle_t *newpool;
|
|
root = (alloc_root_t *) malloc(sizeof(alloc_root_t));
|
|
if (root == NULL) return(NULL);
|
|
if ( (root->first = AllocHdr()) == NULL) return(NULL);
|
|
root->current = root->first;
|
|
newpool = (alloc_handle_t *) root;
|
|
return(newpool);
|
|
}
|
|
|
|
|
|
/*
|
|
** Alloc()
|
|
**
|
|
** Use as a direct replacement for malloc(). Allocates
|
|
** memory from the current pool.
|
|
*/
|
|
|
|
DLLEXPORT char *Alloc(long size)
|
|
{
|
|
alloc_hdr_t *hdr = root->current;
|
|
char *ptr;
|
|
|
|
/*
|
|
** Align to 4 byte boundary - should be ok for most machines.
|
|
** Change this if your machine has weird alignment requirements.
|
|
*/
|
|
size = (size + 3) & 0xfffffffc;
|
|
|
|
ptr = hdr->free;
|
|
hdr->free += size;
|
|
|
|
/* Check if the current block is exhausted. */
|
|
|
|
if (hdr->free >= hdr->end)
|
|
{
|
|
/* Is the next block already allocated? */
|
|
|
|
if (hdr->next != NULL)
|
|
{
|
|
/* re-use block */
|
|
hdr->next->free = hdr->next->block;
|
|
root->current = hdr->next;
|
|
}
|
|
else
|
|
{
|
|
/* extend the pool with a new block */
|
|
if ( (hdr->next = AllocHdr()) == NULL) return(NULL);
|
|
root->current = hdr->next;
|
|
}
|
|
|
|
/* set ptr to the first location in the next block */
|
|
ptr = root->current->free;
|
|
root->current->free += size;
|
|
}
|
|
|
|
/* Return pointer to allocated memory. */
|
|
|
|
return(ptr);
|
|
}
|
|
|
|
|
|
/*
|
|
** AllocSetPool()
|
|
**
|
|
** Change the current pool. Return the old pool.
|
|
*/
|
|
|
|
DLLEXPORT alloc_handle_t * AllocSetPool(alloc_handle_t *newpool)
|
|
{
|
|
alloc_handle_t *old = (alloc_handle_t *) root;
|
|
root = (alloc_root_t *) newpool;
|
|
return(old);
|
|
}
|
|
|
|
|
|
/*
|
|
** AllocReset()
|
|
**
|
|
** Reset the current pool for re-use. No memory is freed,
|
|
** so this is very fast.
|
|
*/
|
|
|
|
DLLEXPORT void AllocReset()
|
|
{
|
|
root->current = root->first;
|
|
root->current->free = root->current->block;
|
|
}
|
|
|
|
|
|
/*
|
|
** AllocFreePool()
|
|
**
|
|
** Free the memory used by the current pool.
|
|
** Don't use where AllocReset() could be used.
|
|
*/
|
|
|
|
DLLEXPORT void AllocFreePool()
|
|
{
|
|
alloc_hdr_t *tmp,
|
|
*hdr = root->first;
|
|
|
|
while (hdr != NULL)
|
|
{
|
|
tmp = hdr->next;
|
|
free((char *) hdr->block);
|
|
free((char *) hdr);
|
|
hdr = tmp;
|
|
}
|
|
free((char *) root);
|
|
root = NULL;
|
|
}
|