mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-01-30 16:10:44 +08:00
fix bug in memio.c realloc code
This commit is contained in:
parent
3e444c39d8
commit
353b7ebf53
4
cf
4
cf
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user