fix bug in memio.c realloc code

This commit is contained in:
Dennis Heimbigner 2012-04-12 02:06:28 +00:00
parent 3e444c39d8
commit 353b7ebf53
4 changed files with 40 additions and 27 deletions

4
cf
View File

@ -6,7 +6,7 @@ cmds=$@
fi fi
#HDF5=1 #HDF5=1
#DAP=1 DAP=1
#CDMR=1 #CDMR=1
#RPC=1 #RPC=1
#PGI=1 #PGI=1
@ -19,7 +19,7 @@ cmds=""
#cmds="all" #cmds="all"
#cmds="all check" #cmds="all check"
#cmds="all dist" #cmds="all dist"
cmds="all distcheck" #cmds="all distcheck"
#cmds="$cmds install" #cmds="$cmds install"
fi fi

View File

@ -18,6 +18,12 @@
#endif #endif
#include "nc.h" #include "nc.h"
#undef DEBUG
#ifdef DEBUG
#include <stdio.h>
#endif
#ifndef HAVE_SSIZE_T #ifndef HAVE_SSIZE_T
#define ssize_t int #define ssize_t int
#endif #endif
@ -60,13 +66,6 @@
#undef X_ALIGN #undef X_ALIGN
#endif #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 */ /* Private data for memio */
typedef struct NCMEMIO { typedef struct NCMEMIO {
@ -90,6 +89,8 @@ static int memio_close(ncio* nciop, int);
/* Mnemonic */ /* Mnemonic */
#define DOOPEN 1 #define DOOPEN 1
static long pagesize = 0;
/* Create a new ncio struct to hold info about the file. */ /* Create a new ncio struct to hold info about the file. */
static int static int
memio_new(const char* path, int ioflags, off_t initialsize, ncio** nciopp, NCMEMIO** memiop) 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; ncio* nciop = NULL;
NCMEMIO* memio = NULL; NCMEMIO* memio = NULL;
int openfd = -1; int openfd = -1;
if(pagesize == 0) {
#if defined HAVE_SYSCONF #if defined HAVE_SYSCONF
long pagesize = sysconf(_SC_PAGE_SIZE); pagesize = sysconf(_SC_PAGE_SIZE);
#elif defined HAVE_GETPAGESIZE #elif defined HAVE_GETPAGESIZE
long pagesize = getpagesize(); pagesize = getpagesize();
#else #else
long pagesize = 4096; /* good guess */ pagesize = 4096; /* good guess */
#endif #endif
}
errno = 0; errno = 0;
/* Always force the allocated size to be a multiple of pagesize */ /* 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;} if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;}
} /*!persist*/ } /*!persist*/
#ifdef DEBUG
fprintf(stderr,"memio_create: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc);
#endif
fd = nc__pseudofd(); fd = nc__pseudofd();
*((int* )&nciop->fd) = fd; *((int* )&nciop->fd) = fd;
@ -234,7 +243,7 @@ memio_create(const char* path, int ioflags,
} }
/* Pick a default sizehint */ /* Pick a default sizehint */
if(sizehintp) *sizehintp = DEFAULT_BLOCKSIZE; if(sizehintp) *sizehintp = pagesize;
*nciopp = nciop; *nciopp = nciop;
return NC_NOERR; return NC_NOERR;
@ -309,6 +318,10 @@ memio_open(const char* path,
memio->memory = (char*)malloc(memio->alloc); memio->memory = (char*)malloc(memio->alloc);
if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;} 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 */ /* Read the file into the memio memory */
/* We need to do multiple reads because there is no /* We need to do multiple reads because there is no
guarantee that the amount read will be the full amount */ 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)) if(!fIsSet(nciop->ioflags, NC_WRITE))
return EPERM; /* attempt to write readonly file*/ return EPERM; /* attempt to write readonly file*/
/* Realloc the allocated memory */
if(memio->locked > 0) if(memio->locked > 0)
return NC_EDISKLESS; return NC_EDISKLESS;
if(length > memio->alloc) { if(length > memio->alloc) {
off_t newsize; /* Realloc the allocated memory to a multiple of the pagesize*/
char* newmem; off_t newsize = length;
switch(TACTIC) { void* newmem = NULL;
case TACTIC_DOUBLE: /* Round to a multiple of pagesize */
newsize = (memio->alloc * 2); if((newsize % pagesize) != 0)
break; newsize += (pagesize - (newsize % pagesize));
case TACTIC_INCR:
default:
newsize = length + (length % DEFAULT_BLOCKSIZE);
break;
}
newmem = (char*)realloc(memio->memory,newsize); newmem = (char*)realloc(memio->memory,newsize);
if(newmem == NULL) return NC_ENOMEM; if(newmem == NULL) return NC_ENOMEM;
/* zero out the extra memory */ /* zero out the extra memory */
memset((void*)(newmem+memio->alloc),0,(newsize - memio->alloc)); 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->memory = newmem;
memio->alloc = newsize; memio->alloc = newsize;
} }

View File

@ -17,7 +17,8 @@ main(int argc, char **argv)
printf("\n*** Testing netcdf file functions some more.\n"); printf("\n*** Testing netcdf file functions some more.\n");
#ifdef USE_DAP #ifdef USE_DAP
#ifdef ENABLE_DAP_REMOTE_TESTS #ifdef ENABLE_DAP_REMOTE_TESTS
printf("*** testing simple opendap open/close..."); printf("*** testing simple opendap open/close...");
printf(" url=%s\n",URL);
{ {
int ncid; int ncid;

View File

@ -6,7 +6,6 @@
but they use HDF5 the same way that netCDF-4 does, so if these 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. tests don't work, than netCDF-4 won't work either.
$Id$
*/ */
#include <config.h> #include <config.h>
#include <nc_tests.h> #include <nc_tests.h>