mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-27 07:30:33 +08:00
added list of configure flags to man4/install.doc
This commit is contained in:
parent
df361a2891
commit
e29a6fb164
@ -66,6 +66,11 @@ if BUILD_RPC
|
||||
LIBRPC = librpc
|
||||
endif
|
||||
|
||||
# Define Test directories
|
||||
if BUILD_TESTSETS
|
||||
TESTDIRS = $(V2_TEST) nc_test $(NC_TEST4) $(NCDAPTESTDIR)
|
||||
endif
|
||||
|
||||
WIN32=win32
|
||||
|
||||
# This is the list of subdirs for which Makefiles will be constructed
|
||||
@ -74,8 +79,8 @@ WIN32=win32
|
||||
SUBDIRS = include $(H5_TEST_DIR) libdispatch $(OCLIB) libsrc \
|
||||
$(LIBSRC4_DIR) $(DAP2) $(LIBCDMR) $(LIBRPC) liblib \
|
||||
$(NCGEN3) $(NCGEN) $(NCDUMP) \
|
||||
$(V2_TEST) nc_test $(NC_TEST4) $(NCDAPTESTDIR) man4 \
|
||||
$(EXAMPLES) $(WIN32)
|
||||
$(TESTDIRS) \
|
||||
man4 $(EXAMPLES) $(WIN32)
|
||||
|
||||
# Remove these generated files, for a distclean.
|
||||
DISTCLEANFILES = VERSION comps.txt test_prog
|
||||
|
5
cf
5
cf
@ -6,7 +6,7 @@ cmds=$@
|
||||
fi
|
||||
|
||||
#HDF5=1
|
||||
DAP=1
|
||||
#DAP=1
|
||||
#CDMR=1
|
||||
#RPC=1
|
||||
#PGI=1
|
||||
@ -126,8 +126,9 @@ FLAGS="$FLAGS --disable-pnetcdf"
|
||||
#FLAGS="$FLAGS --enable-ffio"
|
||||
#FLAGS="$FLAGS --enable-benchmarks"
|
||||
#FLAGS="$FLAGS --enable-extra-tests"
|
||||
#FLAGS="$FLAGS --enable-large-file-tests"
|
||||
FLAGS="$FLAGS --enable-logging"
|
||||
FLAGS="$FLAGS --enable-large-file-tests"
|
||||
#FLAGS="$FLAGS --disable-testsets"
|
||||
|
||||
FLAGS="$FLAGS --disable-shared"
|
||||
#FLAGS="$FLAGS --enable-shared"
|
||||
|
67
configure.ac
67
configure.ac
@ -355,6 +355,7 @@ dnl fi
|
||||
nc_build_c=yes
|
||||
nc_build_v2=yes
|
||||
nc_build_utilities=yes
|
||||
nc_build_tests=yes
|
||||
nc_build_examples=yes
|
||||
|
||||
# Does the user want to build examples?
|
||||
@ -389,6 +390,16 @@ test "x$enable_utilities" = xno && nc_build_utilities=no
|
||||
AC_MSG_RESULT($nc_build_utilities)
|
||||
AM_CONDITIONAL(BUILD_UTILITIES, [test x$nc_build_utilities = xyes])
|
||||
|
||||
# Does the user want to disable all tests?
|
||||
AC_MSG_CHECKING([whether test should be built and run])
|
||||
AC_ARG_ENABLE([testsets],
|
||||
[AS_HELP_STRING([--disable-testsets],
|
||||
[don't build or run netCDF tests])])
|
||||
test "x$enable_testsets" = xno || enable_testsets=yes
|
||||
nc_build_tests=$enable_testsets
|
||||
AC_MSG_RESULT($nc_build_tests)
|
||||
AM_CONDITIONAL(BUILD_TESTSETS, [test x$nc_build_tests = xyes])
|
||||
|
||||
# Does the user want to run tests for large files (> 2GiB)?
|
||||
AC_MSG_CHECKING([whether large file (> 2GB) tests should be run])
|
||||
AC_ARG_ENABLE([large-file-tests],
|
||||
@ -562,8 +573,30 @@ AC_CHECK_FUNCS([strlcat strerror snprintf strchr strrchr strcat strcpy \
|
||||
getrlimit gettimeofday fsync MPI_Comm_f2c])
|
||||
|
||||
# check for memio support
|
||||
AC_FUNC_MMAP
|
||||
AC_CHECK_FUNCS([memmove getpagesize sysconf mremap])
|
||||
AC_CHECK_FUNCS([memmove getpagesize sysconf])
|
||||
|
||||
# MMap disabled until I can figure out why it doesn't work
|
||||
# Does the user want to use the mmap for NC_DISKLESS?
|
||||
#AC_MSG_CHECKING([whether mmap will be used for in-memory files])
|
||||
#AC_ARG_ENABLE([mmap],
|
||||
# [AS_HELP_STRING([--enable-mmap],
|
||||
# [use mmap for in-memory (NC_DISKLESS) files])])
|
||||
#test "x$enable_mmap" = xyes || enable_mmap=no
|
||||
#AC_MSG_RESULT($enable_mmap)
|
||||
|
||||
# Only define if mmap and mremap are available
|
||||
#AC_FUNC_MMAP
|
||||
#AC_CHECK_FUNCS([mremap])
|
||||
#if "x$ac_cv_func_mmap_fixed_mapped" != xyes -o "x$ac_cv_func_mremap" != xyes ; then
|
||||
# echo "mmap function or mremap function is not available: disabling mmap"
|
||||
# enable_mmap=no
|
||||
#fi
|
||||
enable_mmap=no
|
||||
|
||||
if test "x$enable_mmap" = xyes; then
|
||||
AC_DEFINE([USE_MMAP], [1], [if true, use mmap for in-memory files])
|
||||
fi
|
||||
AM_CONDITIONAL(USE_MMAP, [test x$enable_mmap = xyes])
|
||||
|
||||
AC_FUNC_ALLOCA
|
||||
AC_CHECK_DECLS([isnan, isinf, isfinite, signbit],,,[#include <math.h>])
|
||||
@ -722,36 +755,6 @@ AC_MSG_RESULT([$BINFILE_NAME $FC $CXX])
|
||||
|
||||
UD_FTPBINDIR
|
||||
|
||||
##################################################
|
||||
# OC has been modified to not depend on xdr.h, so suppress here
|
||||
## Require some version of xdr/rpc if --enable-dap is set.
|
||||
## See if autoconf can find it; check libc, librpc, librpcsvc and libnsl
|
||||
#if test "x$enable_dap" = xyes; then
|
||||
# AC_SEARCH_LIBS([xdr_void],[c rpc nsl rpcsvc],
|
||||
# [dap_xdrlib=$ac_res],[dap_xdrlib=])
|
||||
# if test -z "$dap_xdrlib" -a "x$enable_dap" = "xyes"; then
|
||||
# AC_MSG_ERROR(Cannot locate library containing xdr functions.)
|
||||
# else
|
||||
# if test "$dap_xdrlib" = "lc" ; then
|
||||
# AC_MSG_NOTICE(XDR Functions appear to be in libc.)
|
||||
# elif test "$dap_xdrlib" = "none required" ; then
|
||||
# AC_MSG_NOTICE(XDR Functions appear to be in libc.)
|
||||
# else
|
||||
# dap_xdrlib=`echo $dap_xdrlib | sed -e s/-l//g`
|
||||
# AC_MSG_NOTICE(XDR Functions appear to be in lib${dap_xdrlib}.)
|
||||
# # Add to library list
|
||||
# AC_CHECK_LIB($dap_xdrlib,xdr_void)
|
||||
# fi
|
||||
# # Fix to get working on OS X (thanks to Fedor Baart)
|
||||
# AC_CHECK_HEADERS([rpc/types.h rpc/xdr.h], [
|
||||
# AC_DEFINE([HAVE_RPC_TYPES_H], [], [no rpc/types.h])
|
||||
# AC_DEFINE([HAVE_RPC_XDR_H], [], [no rpc/xdr.h])
|
||||
# ], [], [[#ifdef HAVE_RPC_TYPES_H
|
||||
# # include <rpc/types.h>
|
||||
# #endif]])
|
||||
#fi
|
||||
#fi
|
||||
|
||||
AC_MSG_CHECKING([value of LIBS])
|
||||
AC_MSG_RESULT([$LIBS])
|
||||
|
||||
|
@ -16,7 +16,13 @@ endif # BUILD_DLL
|
||||
# These files comprise the netCDF-3 classic library code.
|
||||
libnetcdf3_la_SOURCES = v1hpg.c onstack.h \
|
||||
nclistmgr.c putget.c attr.c nc3dispatch.c nc.c var.c dim.c ncx.c \
|
||||
ncx.h lookup3.c pstdint.h ncio.c ncio.h memio.c
|
||||
ncx.h lookup3.c pstdint.h ncio.c ncio.h
|
||||
|
||||
if USE_MMAP
|
||||
libnetcdf3_la_SOURCES += mmap.c
|
||||
else
|
||||
libnetcdf3_la_SOURCES += memio.c
|
||||
endif
|
||||
|
||||
# Does the user want to use ffio, a replacement for posixio for Cray
|
||||
# computers?
|
||||
|
596
libsrc/mmap.c
Normal file
596
libsrc/mmap.c
Normal file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
* Copyright 1996, University Corporation for Atmospheric Research
|
||||
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#ifdef _MSC_VER /* Microsoft Compilers */
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include "nc.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifndef MAP_ANONYMOUS
|
||||
# ifdef MAP_ANON
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* !MAP_ANONYMOUS => !HAVE_MMAP */
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#error mmap not fully implemented: missing MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
/* This is conditionalized by __USE_GNU ; why? */
|
||||
extern void *mremap(void*,size_t,size_t,int);
|
||||
# ifndef MREMAP_MAYMOVE
|
||||
# define MREMAP_MAYMOVE 1
|
||||
# endif
|
||||
#endif /*HAVE_MMAP*/
|
||||
|
||||
#ifndef HAVE_SSIZE_T
|
||||
#define ssize_t int
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
#endif
|
||||
|
||||
/* Define the mode flags for create: rw by owner, no access by anyone else */
|
||||
#define OPENMODE 0600
|
||||
#define OPENANYMODE 0666
|
||||
|
||||
#include "ncio.h"
|
||||
#include "fbits.h"
|
||||
#include "rnd.h"
|
||||
|
||||
/* #define INSTRUMENT 1 */
|
||||
#if INSTRUMENT /* debugging */
|
||||
#undef NDEBUG
|
||||
#include <stdio.h>
|
||||
#include "instr.h"
|
||||
#endif
|
||||
|
||||
#ifndef MMAP_MAXBLOCKSIZE
|
||||
#define MMAP_MAXBLOCKSIZE 268435456 /* sanity check, about X_SIZE_T_MAX/8 */
|
||||
#endif
|
||||
|
||||
#undef MIN /* system may define MIN somewhere and complain */
|
||||
#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn))
|
||||
|
||||
#if !defined(NDEBUG) && !defined(X_INT_MAX)
|
||||
#define X_INT_MAX 2147483647
|
||||
#endif
|
||||
|
||||
#if 0 /* !defined(NDEBUG) && !defined(X_ALIGN) */
|
||||
#define X_ALIGN 4
|
||||
#else
|
||||
#undef X_ALIGN
|
||||
#endif
|
||||
|
||||
/* Private data for memio */
|
||||
|
||||
typedef struct NCMEMIO {
|
||||
int locked; /* => we cannot realloc */
|
||||
int persist; /* => save to a file; triggered by NC_WRITE */
|
||||
char* memory;
|
||||
off_t alloc;
|
||||
off_t size;
|
||||
off_t pos;
|
||||
int mapfd;
|
||||
} NCMEMIO;
|
||||
|
||||
/* Forward */
|
||||
static int mmap_rel(ncio *const nciop, off_t offset, int rflags);
|
||||
static int mmap_get(ncio *const nciop, off_t offset, size_t extent, int rflags, void **const vpp);
|
||||
static int mmap_move(ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags);
|
||||
static int mmap_sync(ncio *const nciop);
|
||||
static int mmap_filesize(ncio* nciop, off_t* filesizep);
|
||||
static int mmap_pad_length(ncio* nciop, off_t length);
|
||||
static int mmap_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
|
||||
mmap_new(const char* path, int ioflags, off_t initialsize, ncio** nciopp, NCMEMIO** memiop)
|
||||
{
|
||||
int status = NC_NOERR;
|
||||
ncio* nciop = NULL;
|
||||
NCMEMIO* memio = NULL;
|
||||
int openfd = -1;
|
||||
|
||||
if(pagesize == 0) {
|
||||
#if defined HAVE_SYSCONF
|
||||
pagesize = sysconf(_SC_PAGE_SIZE);
|
||||
#elif defined HAVE_GETPAGESIZE
|
||||
pagesize = getpagesize();
|
||||
#else
|
||||
pagesize = 4096; /* good guess */
|
||||
#endif
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
/* Always force the allocated size to be a multiple of pagesize */
|
||||
if(initialsize == 0) initialsize = pagesize;
|
||||
if((initialsize % pagesize) != 0)
|
||||
initialsize += (pagesize - (initialsize % pagesize));
|
||||
|
||||
nciop = (ncio* )calloc(1,sizeof(ncio));
|
||||
if(nciop == NULL) {status = NC_ENOMEM; goto fail;}
|
||||
|
||||
nciop->ioflags = ioflags;
|
||||
*((int*)&nciop->fd) = -1; /* caller will fix */
|
||||
|
||||
*((char**)&nciop->path) = strdup(path);
|
||||
if(nciop->path == NULL) {status = NC_ENOMEM; goto fail;}
|
||||
|
||||
*((ncio_relfunc**)&nciop->rel) = mmap_rel;
|
||||
*((ncio_getfunc**)&nciop->get) = mmap_get;
|
||||
*((ncio_movefunc**)&nciop->move) = mmap_move;
|
||||
*((ncio_syncfunc**)&nciop->sync) = mmap_sync;
|
||||
*((ncio_filesizefunc**)&nciop->filesize) = mmap_filesize;
|
||||
*((ncio_pad_lengthfunc**)&nciop->pad_length) = mmap_pad_length;
|
||||
*((ncio_closefunc**)&nciop->close) = mmap_close;
|
||||
|
||||
memio = (NCMEMIO*)calloc(1,sizeof(NCMEMIO));
|
||||
if(memio == NULL) {status = NC_ENOMEM; goto fail;}
|
||||
*((void* *)&nciop->pvt) = memio;
|
||||
|
||||
memio->alloc = initialsize;
|
||||
|
||||
memio->memory = NULL;
|
||||
memio->size = 0;
|
||||
memio->pos = 0;
|
||||
memio->persist = fIsSet(ioflags,NC_WRITE);
|
||||
|
||||
/* See if ok to use mmap */
|
||||
if(sizeof(void*) < 8 && fIsSet(ioflags,NC_64BIT_OFFSET))
|
||||
return NC_DISKLESS; /* cannot support */
|
||||
memio->mapfd = -1;
|
||||
|
||||
if(nciopp) *nciopp = nciop;
|
||||
if(memiop) *memiop = memio;
|
||||
|
||||
done:
|
||||
if(openfd >= 0) close(openfd);
|
||||
return status;
|
||||
|
||||
fail:
|
||||
if(nciop != NULL) {
|
||||
if(nciop->path != NULL) free((char*)nciop->path);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Create a file, and the ncio struct to go with it. This function is
|
||||
only called from nc__create_mp.
|
||||
|
||||
path - path of file to create.
|
||||
ioflags - flags from nc_create
|
||||
initialsz - From the netcdf man page: "The argument
|
||||
Iinitialsize sets the initial size of the file at creation time."
|
||||
igeto -
|
||||
igetsz -
|
||||
sizehintp - the size of a page of data for buffered reads and writes.
|
||||
nciopp - pointer to a pointer that will get location of newly
|
||||
created and inited ncio struct.
|
||||
mempp - pointer to pointer to the initial memory read.
|
||||
*/
|
||||
int
|
||||
mmap_create(const char* path, int ioflags,
|
||||
size_t initialsz,
|
||||
off_t igeto, size_t igetsz, size_t* sizehintp,
|
||||
ncio* *nciopp, void** const mempp)
|
||||
{
|
||||
ncio* nciop;
|
||||
int fd;
|
||||
int status;
|
||||
NCMEMIO* memio = NULL;
|
||||
int persist = (ioflags & NC_WRITE?1:0);
|
||||
int oflags;
|
||||
|
||||
if(path == NULL ||* path == 0)
|
||||
return NC_EINVAL;
|
||||
|
||||
/* For diskless open has, the file must be classic version 1 or 2.*/
|
||||
if(fIsSet(ioflags,NC_NETCDF4))
|
||||
return NC_EDISKLESS; /* violates constraints */
|
||||
|
||||
status = mmap_new(path, ioflags, initialsz, &nciop, &memio);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
memio->size = 0;
|
||||
|
||||
if(!persist) {
|
||||
memio->mapfd = -1;
|
||||
memio->memory = (char*)mmap(NULL,memio->alloc,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS,
|
||||
memio->mapfd,0);
|
||||
{memio->memory[0] = 0;} /* test writing of the mmap'd memory */
|
||||
} else { /*persist */
|
||||
/* Open the file, but make sure we can write it if needed */
|
||||
oflags = (persist ? O_RDWR : O_RDONLY);
|
||||
#ifdef O_BINARY
|
||||
fSet(oflags, O_BINARY);
|
||||
#endif
|
||||
oflags |= (O_CREAT|O_TRUNC);
|
||||
if(fIsSet(ioflags,NC_NOCLOBBER))
|
||||
oflags |= O_EXCL;
|
||||
#ifdef vms
|
||||
fd = open(path, oflags, 0, "ctx=stm");
|
||||
#else
|
||||
fd = open(path, oflags, OPENMODE);
|
||||
#endif
|
||||
if(fd < 0) {status = errno; goto unwind_open;}
|
||||
memio->mapfd = fd;
|
||||
memio->memory = (char*)mmap(NULL,memio->alloc,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
memio->mapfd,0);
|
||||
{int tst=memio->memory[0];} /* test reading of the mmap'd memory */
|
||||
} /*!persist*/
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"mmap_create: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc);
|
||||
#endif
|
||||
|
||||
fd = nc__pseudofd();
|
||||
*((int* )&nciop->fd) = fd;
|
||||
|
||||
fSet(nciop->ioflags, NC_WRITE);
|
||||
|
||||
if(igetsz != 0)
|
||||
{
|
||||
status = nciop->get(nciop,
|
||||
igeto, igetsz,
|
||||
RGN_WRITE,
|
||||
mempp);
|
||||
if(status != NC_NOERR)
|
||||
goto unwind_open;
|
||||
}
|
||||
|
||||
/* Pick a default sizehint */
|
||||
if(sizehintp) *sizehintp = pagesize;
|
||||
|
||||
*nciopp = nciop;
|
||||
return NC_NOERR;
|
||||
|
||||
unwind_open:
|
||||
mmap_close(nciop,1);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* This function opens the data file. It is only called from nc.c,
|
||||
from nc__open_mp and nc_delete_mp.
|
||||
|
||||
path - path of data file.
|
||||
ioflags - flags passed into nc_open.
|
||||
igeto - looks like this function can do an initial page get, and
|
||||
igeto is going to be the offset for that. But it appears to be
|
||||
unused
|
||||
igetsz - the size in bytes of initial page get (a.k.a. extent). Not
|
||||
ever used in the library.
|
||||
sizehintp - the size of a page of data for buffered reads and writes.
|
||||
nciopp - pointer to pointer that will get address of newly created
|
||||
and inited ncio struct.
|
||||
mempp - pointer to pointer to the initial memory read.
|
||||
*/
|
||||
int
|
||||
mmap_open(const char* path,
|
||||
int ioflags,
|
||||
off_t igeto, size_t igetsz, size_t* sizehintp,
|
||||
ncio* *nciopp, void** const mempp)
|
||||
{
|
||||
ncio* nciop;
|
||||
int fd;
|
||||
int status;
|
||||
int persist = (fIsSet(ioflags,NC_WRITE)?1:0);
|
||||
int oflags;
|
||||
NCMEMIO* memio = NULL;
|
||||
size_t sizehint;
|
||||
off_t filesize;
|
||||
|
||||
if(path == NULL ||* path == 0)
|
||||
return EINVAL;
|
||||
|
||||
assert(sizehintp != NULL);
|
||||
sizehint = *sizehintp;
|
||||
|
||||
/* Open the file, but make sure we can write it if needed */
|
||||
oflags = (persist ? O_RDWR : O_RDONLY);
|
||||
#ifdef O_BINARY
|
||||
fSet(oflags, O_BINARY);
|
||||
#endif
|
||||
oflags |= O_EXCL;
|
||||
#ifdef vms
|
||||
fd = open(path, oflags, 0, "ctx=stm");
|
||||
#else
|
||||
fd = open(path, oflags, OPENMODE);
|
||||
#endif
|
||||
if(fd < 0) {status = errno; goto unwind_open;}
|
||||
|
||||
/* get current filesize = max(|file|,initialize)*/
|
||||
filesize = lseek(fd,0,SEEK_END);
|
||||
if(filesize < 0) {status = errno; goto unwind_open;}
|
||||
/* move pointer back to beginning of file */
|
||||
(void)lseek(fd,0,SEEK_SET);
|
||||
if(filesize < (off_t)sizehint)
|
||||
filesize = (off_t)sizehint;
|
||||
|
||||
status = mmap_new(path, ioflags, filesize, &nciop, &memio);
|
||||
if(status != NC_NOERR)
|
||||
return status;
|
||||
memio->size = filesize;
|
||||
|
||||
memio->mapfd = fd;
|
||||
memio->memory = (char*)mmap(NULL,memio->alloc,
|
||||
persist?(PROT_READ|PROT_WRITE):(PROT_READ),
|
||||
MAP_SHARED,
|
||||
memio->mapfd,0);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"mmap_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 */
|
||||
{
|
||||
off_t red = memio->size;
|
||||
char* pos = memio->memory;
|
||||
while(red > 0) {
|
||||
ssize_t count = read(fd, pos, red);
|
||||
if(count < 0)
|
||||
{close(fd); status = errno; goto unwind_open;}
|
||||
if(count == 0)
|
||||
{close(fd); status = NC_ENOTNC; goto unwind_open;}
|
||||
red -= count;
|
||||
pos += count;
|
||||
}
|
||||
}
|
||||
(void)close(fd); /* until mmap_close() */
|
||||
|
||||
/* Use half the filesize as the blocksize */
|
||||
sizehint = filesize/2;
|
||||
|
||||
fd = nc__pseudofd();
|
||||
*((int* )&nciop->fd) = fd;
|
||||
|
||||
if(igetsz != 0)
|
||||
{
|
||||
status = nciop->get(nciop,
|
||||
igeto, igetsz,
|
||||
0,
|
||||
mempp);
|
||||
if(status != NC_NOERR)
|
||||
goto unwind_open;
|
||||
}
|
||||
|
||||
*sizehintp = sizehint;
|
||||
*nciopp = nciop;
|
||||
return NC_NOERR;
|
||||
|
||||
unwind_open:
|
||||
mmap_close(nciop,0);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get file size in bytes.
|
||||
*/
|
||||
static int
|
||||
mmap_filesize(ncio* nciop, off_t* filesizep)
|
||||
{
|
||||
NCMEMIO* memio;
|
||||
if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL;
|
||||
memio = (NCMEMIO*)nciop->pvt;
|
||||
if(filesizep != NULL) *filesizep = memio->size;
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sync any changes to disk, then truncate or extend file so its size
|
||||
* is length. This is only intended to be called before close, if the
|
||||
* file is open for writing and the actual size does not match the
|
||||
* calculated size, perhaps as the result of having been previously
|
||||
* written in NOFILL mode.
|
||||
*/
|
||||
static int
|
||||
mmap_pad_length(ncio* nciop, off_t length)
|
||||
{
|
||||
NCMEMIO* memio;
|
||||
if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL;
|
||||
memio = (NCMEMIO*)nciop->pvt;
|
||||
|
||||
if(!fIsSet(nciop->ioflags, NC_WRITE))
|
||||
return EPERM; /* attempt to write readonly file*/
|
||||
|
||||
if(memio->locked > 0)
|
||||
return NC_EDISKLESS;
|
||||
|
||||
if(length > memio->alloc) {
|
||||
/* 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*)mremap(memio->memory,memio->alloc,newsize,MREMAP_MAYMOVE);
|
||||
if(newmem == NULL) return NC_ENOMEM;
|
||||
|
||||
#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;
|
||||
}
|
||||
memio->size = length;
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
/* Write out any dirty buffers to disk and
|
||||
ensure that next read will get data from disk.
|
||||
Sync any changes, then close the open file associated with the ncio
|
||||
struct, and free its memory.
|
||||
nciop - pointer to ncio to close.
|
||||
doUnlink - if true, unlink file
|
||||
*/
|
||||
|
||||
static int
|
||||
mmap_close(ncio* nciop, int doUnlink)
|
||||
{
|
||||
int status = NC_NOERR;
|
||||
NCMEMIO* memio;
|
||||
if(nciop == NULL || nciop->pvt == NULL) return NC_NOERR;
|
||||
|
||||
memio = (NCMEMIO*)nciop->pvt;
|
||||
assert(memio != NULL);
|
||||
|
||||
/* Since we are using mmap, persisting to a file should be automatic */
|
||||
status = munmap(memio->memory,memio->alloc);
|
||||
memio->memory = NULL; /* so we do not try to free it */
|
||||
|
||||
/* Close file if it was open */
|
||||
if(memio->mapfd >= 0)
|
||||
close(memio->mapfd);
|
||||
|
||||
/* do cleanup */
|
||||
if(memio != NULL) free(memio);
|
||||
if(nciop->path != NULL) free((char*)nciop->path);
|
||||
free(nciop);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
guarantee(ncio* nciop, off_t endpoint)
|
||||
{
|
||||
NCMEMIO* memio = (NCMEMIO*)nciop->pvt;
|
||||
if(endpoint > memio->alloc) {
|
||||
/* extend the allocated memory and size */
|
||||
int status = mmap_pad_length(nciop,endpoint);
|
||||
if(status != NC_NOERR) return status;
|
||||
}
|
||||
if(memio->size < endpoint)
|
||||
memio->size = endpoint;
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Request that the region (offset, extent)
|
||||
* be made available through *vpp.
|
||||
*/
|
||||
static int
|
||||
mmap_get(ncio* const nciop, off_t offset, size_t extent, int rflags, void** const vpp)
|
||||
{
|
||||
int status = NC_NOERR;
|
||||
NCMEMIO* memio;
|
||||
if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL;
|
||||
memio = (NCMEMIO*)nciop->pvt;
|
||||
status = guarantee(nciop, offset+extent);
|
||||
memio->locked++;
|
||||
if(status != NC_NOERR) return status;
|
||||
if(vpp) *vpp = memio->memory+offset;
|
||||
return NC_NOERR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Like memmove(), safely move possibly overlapping data.
|
||||
*/
|
||||
static int
|
||||
mmap_move(ncio* const nciop, off_t to, off_t from, size_t nbytes, int ignored)
|
||||
{
|
||||
int status = NC_NOERR;
|
||||
NCMEMIO* memio;
|
||||
|
||||
if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL;
|
||||
memio = (NCMEMIO*)nciop->pvt;
|
||||
if(from < to) {
|
||||
/* extend if "to" is not currently allocated */
|
||||
status = guarantee(nciop,to+nbytes);
|
||||
if(status != NC_NOERR) return status;
|
||||
}
|
||||
/* check for overlap */
|
||||
if((to + nbytes) > from || (from + nbytes) > to) {
|
||||
/* Ranges overlap */
|
||||
#ifdef HAVE_MEMMOVE
|
||||
memmove((void*)(memio->memory+to),(void*)(memio->memory+from),nbytes);
|
||||
#else
|
||||
off_t overlap;
|
||||
off_t nbytes1;
|
||||
if((from + nbytes) > to) {
|
||||
overlap = ((from + nbytes) - to); /* # bytes of overlap */
|
||||
nbytes1 = (nbytes - overlap); /* # bytes of non-overlap */
|
||||
/* move the non-overlapping part */
|
||||
memcpy((void*)(memio->memory+(to+overlap)),
|
||||
(void*)(memio->memory+(from+overlap)),
|
||||
nbytes1);
|
||||
/* move the overlapping part */
|
||||
memcpy((void*)(memio->memory+to),
|
||||
(void*)(memio->memory+from),
|
||||
overlap);
|
||||
} else { /*((to + nbytes) > from) */
|
||||
overlap = ((to + nbytes) - from); /* # bytes of overlap */
|
||||
nbytes1 = (nbytes - overlap); /* # bytes of non-overlap */
|
||||
/* move the non-overlapping part */
|
||||
memcpy((void*)(memio->memory+to),
|
||||
(void*)(memio->memory+from),
|
||||
nbytes1);
|
||||
/* move the overlapping part */
|
||||
memcpy((void*)(memio->memory+(to+nbytes1)),
|
||||
(void*)(memio->memory+(from+nbytes1)),
|
||||
overlap);
|
||||
}
|
||||
#endif
|
||||
} else {/* no overlap */
|
||||
memcpy((void*)(memio->memory+to),(void*)(memio->memory+from),nbytes);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
mmap_rel(ncio* const nciop, off_t offset, int rflags)
|
||||
{
|
||||
NCMEMIO* memio;
|
||||
if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL;
|
||||
memio = (NCMEMIO*)nciop->pvt;
|
||||
memio->locked--;
|
||||
return NC_NOERR; /* do nothing */
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out any dirty buffers to disk and
|
||||
* ensure that next read will get data from disk.
|
||||
*/
|
||||
static int
|
||||
mmap_sync(ncio* const nciop)
|
||||
{
|
||||
return NC_NOERR; /* do nothing */
|
||||
}
|
@ -16,15 +16,21 @@
|
||||
*/
|
||||
|
||||
/* Define known ncio packages */
|
||||
extern int ffio_create(const char*,int,size_t,off_t,size_t,size_t*,ncio**,void** const);
|
||||
extern int ffio_open(const char*,int,off_t,size_t,size_t*,ncio**,void** const);
|
||||
|
||||
extern int posixio_create(const char*,int,size_t,off_t,size_t,size_t*,ncio**,void** const);
|
||||
extern int posixio_open(const char*,int,off_t,size_t,size_t*,ncio**,void** const);
|
||||
|
||||
#ifdef USE_FFIO
|
||||
extern int ffio_create(const char*,int,size_t,off_t,size_t,size_t*,ncio**,void** const);
|
||||
extern int ffio_open(const char*,int,off_t,size_t,size_t*,ncio**,void** const);
|
||||
#endif
|
||||
|
||||
#ifdef USE_MMAP
|
||||
extern int mmap_create(const char*,int,size_t,off_t,size_t,size_t*,ncio**,void** const);
|
||||
extern int mmap_open(const char*,int,off_t,size_t,size_t*,ncio**,void** const);
|
||||
#else
|
||||
extern int memio_create(const char*,int,size_t,off_t,size_t,size_t*,ncio**,void** const);
|
||||
extern int memio_open(const char*,int,off_t,size_t,size_t*,ncio**,void** const);
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
ncio_create(const char *path, int ioflags, size_t initialsz,
|
||||
@ -32,7 +38,13 @@ ncio_create(const char *path, int ioflags, size_t initialsz,
|
||||
ncio** iopp, void** const mempp)
|
||||
{
|
||||
if(fIsSet(ioflags,NC_DISKLESS))
|
||||
|
||||
#ifdef USE_MMAP
|
||||
return mmap_create(path,ioflags,initialsz,igeto,igetsz,sizehintp,iopp,mempp);
|
||||
#else
|
||||
return memio_create(path,ioflags,initialsz,igeto,igetsz,sizehintp,iopp,mempp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_FFIO
|
||||
return ffio_create(path,ioflags,initialsz,igeto,igetsz,sizehintp,iopp,mempp);
|
||||
#else
|
||||
@ -49,7 +61,11 @@ ncio_open(const char *path, int ioflags,
|
||||
1. file must be classic version 1 or 2
|
||||
*/
|
||||
if(fIsSet(ioflags,NC_DISKLESS)) {
|
||||
#ifdef USE_MMAP
|
||||
return mmap_open(path,ioflags,igeto,igetsz,sizehintp,iopp,mempp);
|
||||
#else
|
||||
return memio_open(path,ioflags,igeto,igetsz,sizehintp,iopp,mempp);
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_FFIO
|
||||
return ffio_open(path,ioflags,igeto,igetsz,sizehintp,iopp,mempp);
|
||||
|
@ -47,6 +47,7 @@ full functionality. (See \ref architecture).
|
||||
- \ref build_classic
|
||||
- \ref build_hdf4
|
||||
- \ref build_parallel
|
||||
- \ref configure_options
|
||||
|
||||
\page build_default Building with NetCDF-4 and the Remote Data Client
|
||||
|
||||
@ -237,4 +238,48 @@ netCDF-4 libraries:
|
||||
cc -o myapp myapp.c `nc-config --cflags --libs`
|
||||
</code>
|
||||
|
||||
\page configure_options ./configure options
|
||||
|
||||
Note: --disable prefix indicates that the option is normally enabled.
|
||||
<table>
|
||||
<tr><th>Option<th>Description<th>Dependencies
|
||||
<tr><td>--disable-doxygen<td>Disable generation of documentation.<td>doxygen
|
||||
<tr><td>--disable-fsync<td>disable fsync support<td>kernel fsync support
|
||||
<tr><td>--enable-valgrind-tests <td>build with valgrind-tests; static builds only<td>valgrind
|
||||
<tr><td>--enable-netcdf-4<td>build with netcdf-4<td>HDF5 and zlib
|
||||
<tr><td>--enable-netcdf4<td>synonym for enable-netcdf-4
|
||||
<tr><td>--enable-hdf4<td>build netcdf-4 with HDF4 read capability<td>HDF4, HDF5 and zlib
|
||||
<tr><td>--enable-hdf4-file-tests<td>test ability to read HDF4 files<td>selected HDF4 files from Unidata ftp site
|
||||
<tr><td>--enable-pnetcdf<td>build netcdf-4 with parallel I/O for classic and
|
||||
64-bit offset files using parallel-netcdf
|
||||
<tr><td>--enable-extra-example-tests<td>Run extra example tests<td>--enable-netcdf-4,GNU sed
|
||||
<tr><td>--enable-parallel-tests <td>run extra parallel IO tests<td>--enable-netcdf-4, parallel IO support
|
||||
<tr><td>--enable-logging<td>enable logging capability<td>--enable-netcdf-4
|
||||
<tr><td>--disable-dap<td>build without DAP client support.<td>libcurl
|
||||
<tr><td>--disable-dap-remote-tests<td>disable dap remote tests<td>--enable-dap
|
||||
<tr><td>--enable-dap-long-tests<td>enable dap long tests<td>
|
||||
<tr><td>--enable-extra-tests<td>run some extra tests that may not pass because of known issues<td>
|
||||
<tr><td>--enable-ffio<td>use ffio instead of posixio (ex. on the Cray)<td>
|
||||
<tr><td>--disable-examples<td>don't build the netCDF examples during make check
|
||||
(examples are treated as extra tests by netCDF)<td>
|
||||
<tr><td>--disable-v2<td>turn off the netCDF version 2 API<td>
|
||||
<tr><td>--disable-utilities<td>don't build netCDF utilities ncgen, ncdump, and nccopy<td>
|
||||
<tr><td>--disable-testsets<td>don't build or run netCDF tests<td>
|
||||
<tr><td>--enable-large-file-tests <td>Run tests which create very large data
|
||||
files<td>~13 GB disk space required, but recovered when
|
||||
tests are complete). See option --with-temp-large to
|
||||
specify temporary directory<td>
|
||||
<tr><td>--enable-benchmarks<td>Run benchmarks. This is an experimental feature.
|
||||
The benchmarks are a
|
||||
bunch of extra tests, which are timed. We use these
|
||||
tests to check netCDF performance.
|
||||
<td>sample data files from the Unidata ftp site
|
||||
<tr><td>--disable-extreme-numbers
|
||||
<td>don't use extreme numbers during testing, such as MAX_INT - 1<td>
|
||||
<tr><td>--enable-dll<td>build a win32 DLL<td>mingw compiler
|
||||
<tr><td>--disable-shared<td>build shared libraries<td>
|
||||
<tr><td>--disable-static<td>build static libraries<td>
|
||||
<tr><td>--disable-largefile<td>omit support for large files<td>
|
||||
</table>
|
||||
*/
|
||||
|
||||
|
@ -25,6 +25,7 @@ utils.h utils.c dimmap.h dimmap.c
|
||||
# This is the man page.
|
||||
man_MANS = ncdump.1 nccopy.1
|
||||
|
||||
if BUILD_TESTSETS
|
||||
if !BUILD_DLL
|
||||
# These tests are run for both netCDF-4 and non-netCDF-4 builds.
|
||||
check_PROGRAMS = rewrite-scalar ctest ctest64 ncdump tst_utf8
|
||||
@ -58,6 +59,31 @@ tst_h_rdc0_CPPFLAGS = -I${top_srcdir}/nc_test ${AM_CPPFLAGS}
|
||||
endif #!USE_NETCDF4
|
||||
endif #!BUILD_DLL
|
||||
|
||||
# Can't run ncgen to generate ctest.c and ctest64.c on cross-compiles.
|
||||
BUILT_SOURCES = ctest.c ctest64.c
|
||||
if EXTRA_TESTS
|
||||
ctest.c:
|
||||
$(top_builddir)/ncgen/ncgen -lc -o ctest0.nc $(top_srcdir)/ncgen/c0.cdl >$(srcdir)/ctest.c
|
||||
|
||||
ctest64.c:
|
||||
$(top_builddir)/ncgen/ncgen -v2 -lc -o ctest0_64.nc $(top_srcdir)/ncgen/c0.cdl > $(srcdir)/ctest64.c
|
||||
else
|
||||
ctest.c:
|
||||
cp ref_ctest.c ctest.c
|
||||
|
||||
ctest64.c:
|
||||
cp ref_ctest64.c ctest64.c
|
||||
endif
|
||||
|
||||
if !BUILD_DLL
|
||||
TESTS += tst_ncgen4_classic.sh
|
||||
if USE_NETCDF4
|
||||
TESTS += tst_ncgen4.sh
|
||||
endif
|
||||
endif
|
||||
|
||||
endif BUILD_TESTSETS
|
||||
|
||||
CLEANFILES = test0.nc test1.cdl test1.nc test2.cdl ctest1.cdl ctest.c \
|
||||
ctest64.c ctest0.nc ctest0_64.nc c1.cdl ctest1_64.cdl c0.nc small.nc \
|
||||
small2.nc c0tmp.nc c1.ncml utf8.cdl utf8_64.cdl utf8.nc utf8_64.nc \
|
||||
@ -98,31 +124,9 @@ ref_tst_charfill.cdl tst_charfill.cdl tst_charfill.sh \
|
||||
tst_iter.sh
|
||||
|
||||
|
||||
# Can't run ncgen to generate ctest.c and ctest64.c on cross-compiles.
|
||||
BUILT_SOURCES = ctest.c ctest64.c
|
||||
if EXTRA_TESTS
|
||||
ctest.c:
|
||||
$(top_builddir)/ncgen/ncgen -lc -o ctest0.nc $(top_srcdir)/ncgen/c0.cdl >$(srcdir)/ctest.c
|
||||
|
||||
ctest64.c:
|
||||
$(top_builddir)/ncgen/ncgen -v2 -lc -o ctest0_64.nc $(top_srcdir)/ncgen/c0.cdl > $(srcdir)/ctest64.c
|
||||
else
|
||||
ctest.c:
|
||||
cp ref_ctest.c ctest.c
|
||||
|
||||
ctest64.c:
|
||||
cp ref_ctest64.c ctest64.c
|
||||
endif
|
||||
|
||||
# NCGEN4 additions
|
||||
SUBDIRS=cdl4 expected4
|
||||
EXTRA_DIST += tst_ncgen4_shared.sh tst_ncgen4.sh tst_ncgen4_classic.sh \
|
||||
tst_ncgen4_diff.sh tst_ncgen4_cycle.sh ref_ctest.c ref_ctest64.c
|
||||
|
||||
CLEANFILES += results/*.nc results/*.dmp results/*.dmp2 tmp*.cdl
|
||||
if !BUILD_DLL
|
||||
TESTS += tst_ncgen4_classic.sh
|
||||
if USE_NETCDF4
|
||||
TESTS += tst_ncgen4.sh
|
||||
endif
|
||||
endif
|
||||
|
Loading…
Reference in New Issue
Block a user