From 353b7ebf536c3a516c7bd8ae0f2fea1136354d12 Mon Sep 17 00:00:00 2001 From: Dennis Heimbigner Date: Thu, 12 Apr 2012 02:06:28 +0000 Subject: [PATCH] fix bug in memio.c realloc code --- cf | 4 +-- libsrc/memio.c | 59 +++++++++++++++++++++++--------------- nc_test4/tst_files6.c | 3 +- nc_test4/tst_h_many_atts.c | 1 - 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/cf b/cf index 2725c01e4..e7b391258 100644 --- a/cf +++ b/cf @@ -6,7 +6,7 @@ cmds=$@ fi #HDF5=1 -#DAP=1 +DAP=1 #CDMR=1 #RPC=1 #PGI=1 @@ -19,7 +19,7 @@ cmds="" #cmds="all" #cmds="all check" #cmds="all dist" -cmds="all distcheck" +#cmds="all distcheck" #cmds="$cmds install" fi diff --git a/libsrc/memio.c b/libsrc/memio.c index c268462d8..688e2db0c 100644 --- a/libsrc/memio.c +++ b/libsrc/memio.c @@ -18,6 +18,12 @@ #endif #include "nc.h" +#undef DEBUG + +#ifdef DEBUG +#include +#endif + #ifndef HAVE_SSIZE_T #define ssize_t int #endif @@ -60,13 +66,6 @@ #undef X_ALIGN #endif -/* Define the amount by which memory is incremented on realloc */ -#define DEFAULT_BLOCKSIZE (0x2000) - -#define TACTIC_INCR 1 -#define TACTIC_DOUBLE 2 -#define TACTIC TACTIC_DOUBLE - /* Private data for memio */ typedef struct NCMEMIO { @@ -90,6 +89,8 @@ static int memio_close(ncio* nciop, int); /* Mnemonic */ #define DOOPEN 1 +static long pagesize = 0; + /* Create a new ncio struct to hold info about the file. */ static int memio_new(const char* path, int ioflags, off_t initialsize, ncio** nciopp, NCMEMIO** memiop) @@ -98,13 +99,17 @@ memio_new(const char* path, int ioflags, off_t initialsize, ncio** nciopp, NCMEM ncio* nciop = NULL; NCMEMIO* memio = NULL; int openfd = -1; + + if(pagesize == 0) { #if defined HAVE_SYSCONF - long pagesize = sysconf(_SC_PAGE_SIZE); + pagesize = sysconf(_SC_PAGE_SIZE); #elif defined HAVE_GETPAGESIZE - long pagesize = getpagesize(); + pagesize = getpagesize(); #else - long pagesize = 4096; /* good guess */ + pagesize = 4096; /* good guess */ #endif + } + errno = 0; /* Always force the allocated size to be a multiple of pagesize */ @@ -218,6 +223,10 @@ memio_create(const char* path, int ioflags, if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;} } /*!persist*/ +#ifdef DEBUG +fprintf(stderr,"memio_create: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc); +#endif + fd = nc__pseudofd(); *((int* )&nciop->fd) = fd; @@ -234,7 +243,7 @@ memio_create(const char* path, int ioflags, } /* Pick a default sizehint */ - if(sizehintp) *sizehintp = DEFAULT_BLOCKSIZE; + if(sizehintp) *sizehintp = pagesize; *nciopp = nciop; return NC_NOERR; @@ -309,6 +318,10 @@ memio_open(const char* path, memio->memory = (char*)malloc(memio->alloc); if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;} +#ifdef DEBUG +fprintf(stderr,"memio_open: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc); +#endif + /* Read the file into the memio memory */ /* We need to do multiple reads because there is no guarantee that the amount read will be the full amount */ @@ -383,28 +396,28 @@ memio_pad_length(ncio* nciop, off_t length) if(!fIsSet(nciop->ioflags, NC_WRITE)) return EPERM; /* attempt to write readonly file*/ - /* Realloc the allocated memory */ if(memio->locked > 0) return NC_EDISKLESS; if(length > memio->alloc) { - off_t newsize; - char* newmem; - switch(TACTIC) { - case TACTIC_DOUBLE: - newsize = (memio->alloc * 2); - break; - case TACTIC_INCR: - default: - newsize = length + (length % DEFAULT_BLOCKSIZE); - break; - } + /* Realloc the allocated memory to a multiple of the pagesize*/ + off_t newsize = length; + void* newmem = NULL; + /* Round to a multiple of pagesize */ + if((newsize % pagesize) != 0) + newsize += (pagesize - (newsize % pagesize)); newmem = (char*)realloc(memio->memory,newsize); if(newmem == NULL) return NC_ENOMEM; + /* zero out the extra memory */ memset((void*)(newmem+memio->alloc),0,(newsize - memio->alloc)); +#ifdef DEBUG +fprintf(stderr,"realloc: %lu/%lu -> %lu/%lu\n", +(unsigned long)memio->memory,(unsigned long)memio->alloc, +(unsigned long)newmem,(unsigned long)newsize); +#endif memio->memory = newmem; memio->alloc = newsize; } diff --git a/nc_test4/tst_files6.c b/nc_test4/tst_files6.c index ab75dd5d7..cb6276859 100644 --- a/nc_test4/tst_files6.c +++ b/nc_test4/tst_files6.c @@ -17,7 +17,8 @@ main(int argc, char **argv) printf("\n*** Testing netcdf file functions some more.\n"); #ifdef USE_DAP #ifdef ENABLE_DAP_REMOTE_TESTS - printf("*** testing simple opendap open/close..."); + printf("*** testing simple opendap open/close..."); + printf(" url=%s\n",URL); { int ncid; diff --git a/nc_test4/tst_h_many_atts.c b/nc_test4/tst_h_many_atts.c index 2ec8ba218..9cb42a10d 100644 --- a/nc_test4/tst_h_many_atts.c +++ b/nc_test4/tst_h_many_atts.c @@ -6,7 +6,6 @@ but they use HDF5 the same way that netCDF-4 does, so if these tests don't work, than netCDF-4 won't work either. - $Id$ */ #include #include