Feature wrapper (#136)
this quite sizable commit does several things, but is primarily focussed on building a toolkit that can run simultaneous simulations/analyses within a shared memory space. Versions <=2.1 use a long list of global variables that prevent multiple instantiations on linux systems without resorting to compilation tricks (like duplicate binaries or similar via static linkage). This version uses a single "Project" pointer to encapsulate the network and analysis data. There are no changes to existing algo implementations other than to accomodate dereferencing of the passed-in pointers. A more detailed list of major changes below: - mirrors all “ENxxxx” function calls with “EN_xxxx” versions (note the underscore) that take an extra first parameter: a pointer to an EN_Project struct, which contains all network, hydraulic, quality, and associated data. - tweaks some code formatting to make it more readable - removes some deprecated/commented code that was sufficiently old - fixes implicit type-cast warnings * Added ENaddnode and ENaddlink functions * More memory reallocations * Added ENInit, ENsetheadcurveindex * Added ENdeletelink and ENdeletenode * restored default behavior for float types * fixed type * Added docstrings for ENinit * cleanup change * moves global rule variables to vars.h * migrates rule structs to typedefs for better readability * char types to proper enums fixes #93 * Change some variable declarations for compatibility Changes to keep compatibility with C89 compilers: variables must be declared at the top of the functions. Remove the use of EN_LinkType in function call as it is not compatible with ENgetnodetype. * Moved declaration of idstodelete to top of function * Updated ENinit function and headers Updated header files with new functions Updated def file with new functions For ENinit changes names of parameters #98 Added enum for headloss formula * Missed these files in 1a033fc * migrates char types to enums fixes #93, supports unified link/node type enums, rather than public/private redefinitions * removing links in reverse-index order maintains proper indexing fixes #96 * style * clarifies curve getter units issue (dox) closes #95 * fixes link/node confusion in ENsetlinktype partially reverts a3bce95dc330a5a297634a303d438e2e1bc41cc9 * partial compilation fix * fixes dox issue * fixes allocation issues with enums - updates style in various places - introduces FlowDirection enum - use snprintf to prevent overflow * fixes enum type cast * updated mac project settings * Use of _snprintf on Windows and remove DLLEXPORT from mempool.h snprintf it not compatible on Windows so we use _snprintf mempool gave starnge compilation errors while removing DLLEXPORT worked. Not sure why these functions needed to be exposed in the DLL? * Revert "Use of _snprintf on Windows and remove DLLEXPORT from mempool.h" This reverts commit 6238f77d47fa0feaabe5836043c006937de433a2. * use of _snprintf instead of snprintf on Windows and removed DLLEXPORT from mempool.h Had compilation errors on mempool.h. Removed DLLEXPORT so solve it. Not sure why there was a need to expose these functions? * Shift indices for Links in ENaddnode Need to shift indices for Links not just Pipes since a pump could be connected directly to a reservoir. Also set the defult base demand to zero (was 5). * Set defualts for madatory link properties in ENaddlink and small fix for ENsetheadcurveindex Relates to #102 and closes #103 * wraps globals into structs, duplicates api functions with objective versions * parse and serialize Comment field for network elements related to #47 * adds getter for head/efficiency curve in EN_getlinkvalue * adds getter for event node index … to return the index of the junction (tank) that triggered the event. * fixes edge case in parsing … where inp files without demands in [JUNCTIONS] and without any [DEMAND] categories will fail. * adds freeing function for project pointer * removes redundant string literals, fixes overrun issue in error message getter function * check for hydraulics already closed * moving error definitions to data file * deprecates ENR err message getter (unused) * updates location of errors data file also begins to expose blind structs to curves and patterns, anticipating buildout of APIs for those. * updates CLI output to reflect executable name as invoked relates to #109 * Feature nrtest (#131) * Initial commit EPANET testing tools. * Initial commit for epanet-nrtestsuite * SWIG wrapper for EPANET outputapi (#118) * Removed pervious version of outputapi and wrapper * SWIG wrapper for EPANET outputapi * Patching cmake build script fixed target for outputapi * Build failing on deprecated test script * Minor changes. Responding to review comments. * Feature nrtest (#121) * Configured python setup to automatically build nrtest tools. * Working on build / testing automation * Adding EPANET 2.0.12 benchmark * Updated Travis yml to run nrtest * Fixing InsecurePlatformWarning * Fixing InsecurePlatformWarning again * Fixing InsecurePlatformWarning * Fixing InsecurePlatformWarning * Fixing InsecurePlatformWarning * Update .travis.yml * Update .travis.yml * Update .travis.yml * Update .travis.yml * Working on configuring python environment and building test tools under Travis CI. * Making gen-config.sh and run-nrtest.sh executable * Debugging .travis.yml * Debugging .travis.yml * Debugging .travis.yml again * Debugging .travis.yml again * debugging travis setup * debugging Travis setup * debugging Travis setup * debugging Travis setup * debugging Travis setup * debugging Travis setup * debugging Travis setup * debugging Travis setup * debugging Travis setup * debugging Travis setup * debugging Travis setup * Fixing bug with __strncpy_chk destlen < len * nrtesting clean up * re-implements fixes from:5eead5ae403c788567a4* removes extraneous build files, moves cmake and updates travis * mirror of 9b37035560f9683f1514b439f7586a5c17bca5bf * Move some variable declarations * More variable declarations * Fix TmpDir * Allocate _defaultModel * Fix EN_addcurve funcrion * Fix for inpfile * Fix writeRuleinInp call * Set MAXMSG to 79 chars * Fix for flow direction * Refactoring testing related python packages and SWIG wrapper bug fix (#139) * Eliminated epanet-reader package. Removed numpy dependency from epanet-output. Fixed reference counting bug in SWIG wrapper. Added error checking to run_nrtest.sh. Added nrtest package to requirements file. * changing buildhome directory * Fixing bug related to preprocessor definition of PI
This commit is contained in:
414
src/mempool.c
414
src/mempool.c
@@ -1,205 +1,209 @@
|
||||
/* 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;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user