Merge pull request #1464 from NetCDF-World-Domination-Council/ejh_next

Remove obsolete _CRAYMPP and LOCKNUMREC macros
This commit is contained in:
Ward Fisher 2019-08-21 14:18:40 -06:00 committed by GitHub
commit 207f2b57fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 413 additions and 296 deletions

View File

@ -21,6 +21,11 @@ test-driver-verbose test_common.in
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = netcdf.pc
# Does the user want to build and run unit tests?
if BUILD_UNIT_TESTS
UNIT_TEST = unit_test
endif # BUILD_UNIT_TESTS
# Does the user want to build the V2 API?
if BUILD_V2
V2_TEST = nctest
@ -85,8 +90,8 @@ endif # BUILD_BENCHMARKS
# Define Test directories
if BUILD_TESTSETS
TESTDIRS = $(V2_TEST) nc_test $(NC_TEST4) $(BENCHMARKS_DIR) \
$(HDF4_TEST_DIR) $(NCDAP2TESTDIR) $(NCDAP4TESTDIR)
TESTDIRS = $(UNIT_TEST) $(V2_TEST) nc_test $(NC_TEST4) \
$(BENCHMARKS_DIR) $(HDF4_TEST_DIR) $(NCDAP2TESTDIR) $(NCDAP4TESTDIR)
endif
# This is the list of subdirs for which Makefiles will be constructed

View File

@ -7,6 +7,13 @@ This file contains a high-level description of this package's evolution. Release
## 4.7.1 - TBD
* [Bug Fix] Remove obsolete _CRAYMPP and LOCKNUMREC macros from
code. Also brought documentation up to date in man page. These macros
were used in ancient times, before modern parallel I/O systems were
developed. Programmers interested in parallel I/O should see
nc_open_par() and nc_create_par().
See [GitHub #1436](https://github.com/Unidata/netcdf-c/issues/1459)
* [Enhancement] Remove obsolete and deprecated functions
nc_set_base_pe() and nc_inq_base_pe() from the dispatch table. (Both
functions are still supported in the library, this is an internal

View File

@ -184,6 +184,14 @@ if test "x$enable_jna" = xyes ; then
AC_DEFINE([JNA], [1], [if true, include jna bug workaround code])
fi
# Does the user want to turn off unit tests (useful for test coverage
# analysis).
AC_ARG_ENABLE([unit-tests],
[AS_HELP_STRING([--disable-unit-tests],
[Disable tests in unit_test directory. Other tests still run.])])
test "x$enable_unit_tests" = xno || enable_unit_tests=yes
AM_CONDITIONAL([BUILD_UNIT_TESTS], [test "x$enable_unit_tests" = xyes])
# Does the user want to build netcdf-4?
AC_MSG_CHECKING([whether we should build netCDF-4])
AC_ARG_ENABLE([netcdf-4], [AS_HELP_STRING([--disable-netcdf-4],
@ -1536,6 +1544,7 @@ AC_CONFIG_FILES([Makefile
ncdump/expected/Makefile
docs/Makefile
docs/images/Makefile
unit_test/Makefile
nctest/Makefile
nc_test4/Makefile
nc_perf/Makefile

View File

@ -1411,47 +1411,29 @@ May be used to change access to a variable from independent to collective data a
.HP
.SH "MPP FUNCTION DESCRIPTIONS"
.LP
Additional functions for use on SGI/Cray MPP machines (_CRAYMPP).
These are used to set and inquire which PE is the base for MPP
for a particular netCDF. These are only relevant when
using the SGI/Cray ``global''
Flexible File I/O layer and desire to have
only a subset of PEs to open the specific netCDF file.
For technical reasons, these functions are available on all platforms.
On a platform other than SGI/Cray MPP, it is as if
only processor available were processor 0.
These functions were used on archaic SGI/Cray MPP machines. These
functions are retained for backward compatibility; the PE arguments
must all be set to zero.
.LP
To use this feature, you need to specify a communicator group and call
CODE(glio_group_mpi(\|)) or CODE(glio_group_shmem(\|)) prior to the netCDF
FREF(open) and FREF(create) calls.
.HP
FDECL(_create_mp, (IPATH(), ICMODE(), IINITSIZE(), IPE(), OCHUNKSIZE(), ONCID()))
.sp
Like FREF(_create) but allows the base PE to be set.
Like FREF(_create).
.sp
The argument ARG(pe) sets the base PE at creation time. In the MPP
environment, FREF(_create) and FREF(create) set the base PE to processor
zero by default.
The argument ARG(pe) must be zero.
.HP
FDECL(_open_mp, (IPATH(), IMODE(), IPE(), OCHUNKSIZE(), ONCID()))
.sp
Like FREF(_open) but allows the base PE to be set.
The argument ARG(pe) sets the base PE at creation time. In the MPP
environment, FREF(_open) and FREF(open) set the base PE to processor
zero by default.
Like FREF(_open).
The argument ARG(pe) must be zero.
.HP
FDECL(inq_base_pe, (INCID(), OPE()))
.sp
Inquires of the netCDF dataset which PE is being used as the base for MPP use.
This is safe to use at any time.
Always returns pe of zero.
.HP
FDECL(set_base_pe, (INCID(), IPE()))
.sp
Resets the base PE for the netCDF dataset.
Only perform this operation when the affected communicator group
synchronizes before and after the call.
This operation is very risky and should only be contemplated
under only the most extreme cases.
This function does nothing.
.SH "ENVIRONMENT VARIABLES"
.TP 4
.B NETCDF_FFIOSPEC

View File

@ -221,15 +221,6 @@ NC_lookupvar(NC3_INFO* ncp, int varid, NC_var **varp);
#define IS_RECVAR(vp) \
((vp)->shape != NULL ? (*(vp)->shape == NC_UNLIMITED) : 0 )
#ifdef LOCKNUMREC
/*
* typedef SHMEM type
* for whenever the SHMEM functions can handle other than shorts
*/
typedef unsigned short int ushmem_t;
typedef short int shmem_t;
#endif
struct NC3_INFO {
/* contains the previous NC during redef. */
NC3_INFO *old;
@ -258,18 +249,6 @@ struct NC3_INFO {
NC_dimarray dims;
NC_attrarray attrs;
NC_vararray vars;
#ifdef LOCKNUMREC
/* size and named indexes for the lock array protecting NC.numrecs */
# define LOCKNUMREC_DIM 4
# define LOCKNUMREC_VALUE 0
# define LOCKNUMREC_LOCK 1
# define LOCKNUMREC_SERVING 2
# define LOCKNUMREC_BASEPE 3
/* Used on Cray T3E MPP to maintain the
* integrity of numrecs for an unlimited dimension
*/
ushmem_t lock[LOCKNUMREC_DIM];
#endif
};
#define NC_readonly(ncp) \
@ -305,7 +284,6 @@ struct NC3_INFO {
#define NC_doNsync(ncp) \
fIsSet((ncp)->flags, NC_NSYNC)
#ifndef LOCKNUMREC
# define NC_get_numrecs(nc3i) \
((nc3i)->numrecs)
@ -314,11 +292,6 @@ struct NC3_INFO {
# define NC_increase_numrecs(nc3i, nrecs) \
{if((nrecs) > (nc3i)->numrecs) ((nc3i)->numrecs = (nrecs));}
#else
size_t NC_get_numrecs(const NC3_INFO *nc3i);
void NC_set_numrecs(NC3_INFO *nc3i, size_t nrecs);
void NC_increase_numrecs(NC3_INFO *nc3i, size_t nrecs);
#endif
/* Begin defined in nc.c */

View File

@ -4,7 +4,7 @@ Main header file for the C API.
Copyright 2018, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014,
2015, 2016, 2017, 2018
2015, 2016, 2017, 2018, 2019
University Corporation for Atmospheric Research/Unidata.
See \ref copyright file for more info.
@ -1760,19 +1760,17 @@ nc_show_metadata(int ncid);
/* End {put,get}_var */
/* #ifdef _CRAYMPP */
/* Delete a file. */
EXTERNL int
nc_delete(const char *path);
/*
* Public interfaces to better support
* CRAY multi-processor systems like T3E.
* A tip of the hat to NERSC.
*/
/*
* It turns out we need to declare and define
* these public interfaces on all platforms
* or things get ugly working out the
* FORTRAN interface. On !_CRAYMPP platforms,
* these functions work as advertised, but you
* can only use "processor element" 0.
* The following functions were written to accomodate the old Cray
* systems. Modern HPC systems do not use these functions any more,
* but use the nc_open_par()/nc_create_par() functions instead. These
* functions are retained for backward compatibibility. These
* functions work as advertised, but you can only use "processor
* element" 0.
*/
EXTERNL int
@ -1783,9 +1781,6 @@ EXTERNL int
nc__open_mp(const char *path, int mode, int basepe,
size_t *chunksizehintp, int *ncidp);
EXTERNL int
nc_delete(const char *path);
EXTERNL int
nc_delete_mp(const char *path, int basepe);
@ -1795,8 +1790,6 @@ nc_set_base_pe(int ncid, int pe);
EXTERNL int
nc_inq_base_pe(int ncid, int *pe);
/* #endif _CRAYMPP */
/* This v2 function is used in the nc_test program. */
EXTERNL int
nctypelen(nc_type datatype);

View File

@ -1,31 +1,39 @@
/*
* Copyright 2018, University Corporation for Atmospheric Research
* Copyright 2018, University Corporation for Atmospheric Research
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*/
/**
* @file
* @internal
*
* This file contains functions that work with the NC struct. There is
* an NC struct for every open netCDF file.
*
* @author Glenn Davis
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#if defined(LOCKNUMREC) /* && _CRAYMPP */
# include <mpp/shmem.h>
# include <intrinsics.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "ncdispatch.h"
/* This is the default create format for nc_create and nc__create. */
/** This is the default create format for nc_create and nc__create. */
static int default_create_format = NC_FORMAT_CLASSIC;
/* These have to do with version numbers. */
#define MAGIC_NUM_LEN 4
#define VER_CLASSIC 1
#define VER_64BIT_OFFSET 2
#define VER_HDF5 3
/**
* Find the NC struct for an open file, using the ncid.
*
* @param ncid The ncid to find.
* @param ncpp Pointer that gets a pointer to the NC.
*
* @return ::NC_NOERR No error.
* @return ::NC_EBADID ncid not found.
* @author Glenn Davis, Dennis Heimbigner
*/
int
NC_check_id(int ncid, NC** ncpp)
{
@ -35,25 +43,45 @@ NC_check_id(int ncid, NC** ncpp)
return NC_NOERR;
}
/**
* Free an NC struct and its related resources. Before this is done,
* be sure to remove the NC from the open file list with
* del_from_NCList().
*
* @param ncp Pointer to the NC struct to be freed.
*
* @author Glenn Davis, Dennis Heimbigner
*/
void
free_NC(NC *ncp)
{
if(ncp == NULL)
return;
return;
if(ncp->path)
free(ncp->path);
free(ncp->path);
if(ncp->model)
free(ncp->model);
free(ncp->model);
/* We assume caller has already cleaned up ncp->dispatchdata */
#if _CRAYMPP && defined(LOCKNUMREC)
shfree(ncp);
#else
free(ncp);
#endif /* _CRAYMPP && LOCKNUMREC */
}
/**
* Create and initialize a new NC struct. The ncid is assigned later.
*
* @param dispatcher
* @param path The name of the file.
* @param mode The open or create mode.
* @param model
* @param ncpp A pointer that gets a pointer to the newlly allocacted
* and initialized NC struct.
*
* @return ::NC_NOERR No error.
* @return ::NC_ENOMEM Out of memory.
* @author Glenn Davis, Dennis Heimbigner
*/
int
new_NC(const NC_Dispatch* dispatcher, const char* path, int mode, NCmodel* model, NC** ncpp)
new_NC(const NC_Dispatch* dispatcher, const char* path, int mode,
NCmodel* model, NC** ncpp)
{
NC *ncp = (NC*)calloc(1,sizeof(NC));
if(ncp == NULL) return NC_ENOMEM;
@ -61,31 +89,40 @@ new_NC(const NC_Dispatch* dispatcher, const char* path, int mode, NCmodel* model
ncp->path = nulldup(path);
ncp->mode = mode;
if((ncp->model = malloc(sizeof(NCmodel)))==NULL)
return NC_ENOMEM;
return NC_ENOMEM;
*ncp->model = *model; /* Make a copy */
if(ncp->path == NULL) { /* fail */
free_NC(ncp);
return NC_ENOMEM;
return NC_ENOMEM;
}
if(ncpp) {
*ncpp = ncp;
*ncpp = ncp;
} else {
free_NC(ncp);
free_NC(ncp);
}
return NC_NOERR;
}
/* This function sets a default create flag that will be logically
or'd to whatever flags are passed into nc_create for all future
calls to nc_create.
Valid default create flags are NC_64BIT_OFFSET, NC_CLOBBER,
NC_LOCK, NC_SHARE. */
/**
* This function sets a default create flag that will be logically
* or'd to whatever flags are passed into nc_create for all future
* calls to nc_create.
*
* @param format The format that should become the default.
* @param old_formatp Pointer that gets the previous default. Ignored
* if NULL.
*
* @return ::NC_NOERR No error.
* @return ::NC_ENOTBUILD Requested format not built with this install.
* @return ::NC_EINVAL Invalid input.
* @author Ed Hartnett, Dennis Heimbigner
*/
int
nc_set_default_format(int format, int *old_formatp)
{
/* Return existing format if desired. */
if (old_formatp)
*old_formatp = default_create_format;
*old_formatp = default_create_format;
/* Make sure only valid format is set. */
#ifndef ENABLE_CDF5
@ -95,7 +132,7 @@ nc_set_default_format(int format, int *old_formatp)
#ifdef USE_HDF5
if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT_OFFSET &&
format != NC_FORMAT_NETCDF4 && format != NC_FORMAT_NETCDF4_CLASSIC &&
format != NC_FORMAT_CDF5)
format != NC_FORMAT_CDF5)
return NC_EINVAL;
#else
if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_NETCDF4_CLASSIC)
@ -108,6 +145,12 @@ nc_set_default_format(int format, int *old_formatp)
return NC_NOERR;
}
/**
* Get the current default format.
*
* @return the default format.
* @author Ed Hartnett
*/
int
nc_get_default_format(void)
{

View File

@ -1,7 +1,15 @@
/*********************************************************************
Copyright 2018, UCAR/Unidata See netcdf/COPYRIGHT file for
copying and redistribution conditions.
*********************************************************************/
*********************************************************************/
/**
* @file
*
* Functions to manage the list of NC structs. There is one NC struct
* for each open file.
*
* @author Dennis Heimbigner
*/
#include "config.h"
#include <stdlib.h>
@ -9,22 +17,40 @@
#include <assert.h>
#include "ncdispatch.h"
/** This shift is applied to the ext_ncid in order to get the index in
* the array of NC. */
#define ID_SHIFT (16)
/** This is the length of the NC list - the number of files that can
* be open at one time. We use 2^16 = 65536 entries in the array, but
* slot 0 is not used, so only 65535 files may be open at one
* time. */
#define NCFILELISTLENGTH 0x10000
/* Version one just allocates the max space (sizeof(NC*)*2^16)*/
/** This is the pointer to the array of NC, one for each open file. */
static NC** nc_filelist = NULL;
/** The number of files currently open. */
static int numfiles = 0;
/* Common */
/**
* How many files are currently open?
*
* @return number of open files.
* @author Dennis Heimbigner
*/
int
count_NCList(void)
{
return numfiles;
}
/**
* Free an empty NCList. @note If list is not empty, or has not been
* allocated, function will silently exit.
*
* @author Dennis Heimbigner
*/
void
free_NCList(void)
{
@ -33,86 +59,156 @@ free_NCList(void)
nc_filelist = NULL;
}
/**
* Add an already-allocated NC to the list. It will be assigned an
* ncid in this function.
*
* If this is the first file to be opened, the nc_filelist will be
* allocated and set to all 0.
*
* The ncid is assigned by finding the first open index in the
* nc_filelist array (skipping index 0). The ncid is this index
* left-shifted ID_SHIFT bits (16). This puts the file ID in the first
* two bytes of the 4-byte integer, and leaves the last two bytes for
* group IDs for netCDF-4 files.
*
* @param ncp Pointer to already-allocated and initialized NC struct.
*
* @return ::NC_NOERR No error.
* @return ::NC_ENOMEM Out of memory.
* @author Dennis Heimbigner
*/
int
add_to_NCList(NC* ncp)
{
int i;
int new_id;
if(nc_filelist == NULL) {
if (!(nc_filelist = calloc(1, sizeof(NC*)*NCFILELISTLENGTH)))
return NC_ENOMEM;
numfiles = 0;
if (!(nc_filelist = calloc(1, sizeof(NC*)*NCFILELISTLENGTH)))
return NC_ENOMEM;
numfiles = 0;
}
new_id = 0; /* id's begin at 1 */
for(i=1; i < NCFILELISTLENGTH; i++) {
if(nc_filelist[i] == NULL) {new_id = i; break;}
if(nc_filelist[i] == NULL) {new_id = i; break;}
}
if(new_id == 0) return NC_ENOMEM; /* no more slots */
nc_filelist[new_id] = ncp;
numfiles++;
new_id = (new_id << ID_SHIFT);
ncp->ext_ncid = new_id;
ncp->ext_ncid = (new_id << ID_SHIFT);
return NC_NOERR;
}
/**
* Delete an NC struct from the list. This happens when the file is
* closed. Relies on all memory in the NC being deallocated after this
* function with freeNC().
*
* @note If the file list is empty, or this NC can't be found in the
* list, this function will silently exit.
*
* @param ncp Pointer to NC to be removed from list.
*
* @author Dennis Heimbigner
*/
void
del_from_NCList(NC* ncp)
{
unsigned int ncid = ((unsigned int)ncp->ext_ncid) >> ID_SHIFT;
if(numfiles == 0 || ncid == 0 || nc_filelist == NULL) return;
if(nc_filelist[ncid] != ncp) return;
unsigned int ncid = ((unsigned int)ncp->ext_ncid) >> ID_SHIFT;
if(numfiles == 0 || ncid == 0 || nc_filelist == NULL) return;
if(nc_filelist[ncid] != ncp) return;
nc_filelist[ncid] = NULL;
numfiles--;
nc_filelist[ncid] = NULL;
numfiles--;
/* If all files have been closed, release the filelist memory. */
if (numfiles == 0)
free_NCList();
/* If all files have been closed, release the filelist memory. */
if (numfiles == 0)
free_NCList();
}
/**
* Find an NC in the list, given an ext_ncid. The NC list is indexed
* with the first two bytes of ext_ncid. (The last two bytes specify
* the group for netCDF4 files, or are zeros for classic files.)
*
* @param ext_ncid The ncid of the file to find.
*
* @return pointer to NC or NULL if not found.
* @author Dennis Heimbigner, Ed Hartnett
*/
NC *
find_in_NCList(int ext_ncid)
{
NC* f = NULL;
unsigned int ncid = ((unsigned int)ext_ncid) >> ID_SHIFT;
if(numfiles > 0 && nc_filelist != NULL && ncid < NCFILELISTLENGTH)
f = nc_filelist[ncid];
NC* f = NULL;
/* Discard the first two bytes of ext_ncid to get ncid. */
unsigned int ncid = ((unsigned int)ext_ncid) >> ID_SHIFT;
/* for classic files, ext_ncid must be a multiple of (1<<ID_SHIFT) */
if (f != NULL && f->model->impl == NC_FORMATX_NC3 && (ext_ncid % (1<<ID_SHIFT)))
return NULL;
/* If we have a filelist, there will be an entry, possibly NULL,
* for this ncid. */
if (nc_filelist)
{
assert(numfiles);
f = nc_filelist[ncid];
}
return f;
/* For classic files, ext_ncid must be a multiple of
* (1<<ID_SHIFT). That is, the group part of the ext_ncid (the
* last two bytes) must be zero. If not, then return NULL, which
* will eventually lead to an NC_EBADID error being returned to
* user. */
if (f != NULL && f->model->impl == NC_FORMATX_NC3 && (ext_ncid % (1<<ID_SHIFT)))
return NULL;
return f;
}
/*
Added to support open by name
*/
/**
* Find an NC in the list using the file name.
*
* @param path Name of the file.
*
* @return pointer to NC or NULL if not found.
* @author Dennis Heimbigner
*/
NC*
find_in_NCList_by_name(const char* path)
{
int i;
NC* f = NULL;
if(nc_filelist == NULL)
return NULL;
for(i=1; i < NCFILELISTLENGTH; i++) {
if(nc_filelist[i] != NULL) {
if(strcmp(nc_filelist[i]->path,path)==0) {
f = nc_filelist[i];
break;
}
}
}
return f;
int i;
NC* f = NULL;
if(nc_filelist == NULL)
return NULL;
for(i=1; i < NCFILELISTLENGTH; i++) {
if(nc_filelist[i] != NULL) {
if(strcmp(nc_filelist[i]->path,path)==0) {
f = nc_filelist[i];
break;
}
}
}
return f;
}
/**
* Find an NC in list based on its index. The index is ((unsigned
* int)ext_ncid) >> ID_SHIFT. This is the two high bytes of the
* ext_ncid. (The other two bytes are used for the group ID for
* netCDF-4 files.)
*
* @param index The index in the NC list.
* @param ncp Pointer that gets pointer to the next NC. Igored if
* NULL.
*
* @return ::NC_NOERR No error.
* @return ::NC_ERANGE Index out of range.
* @author Dennis Heimbigner
*/
int
iterate_NCList(int index, NC** ncp)
{
/* Walk from 0 ...; 0 return => stop */
if(index < 0 || index >= NCFILELISTLENGTH)
return NC_ERANGE;
return NC_ERANGE;
if(ncp) *ncp = nc_filelist[index];
return NC_NOERR;
}

View File

@ -10,10 +10,6 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#if defined(LOCKNUMREC) /* && _CRAYMPP */
# include <mpp/shmem.h>
# include <intrinsics.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@ -47,11 +43,7 @@ free_NC3INFO(NC3_INFO *nc3)
free_NC_dimarrayV(&nc3->dims);
free_NC_attrarrayV(&nc3->attrs);
free_NC_vararrayV(&nc3->vars);
#if _CRAYMPP && defined(LOCKNUMREC)
shfree(nc3);
#else
free(nc3);
#endif /* _CRAYMPP && LOCKNUMREC */
}
static NC3_INFO *
@ -948,21 +940,6 @@ NC_endef(NC3_INFO *ncp,
return ncio_sync(ncp->nciop);
}
#ifdef LOCKNUMREC
static int
NC_init_pe(NC *ncp, int basepe) {
if (basepe < 0 || basepe >= _num_pes()) {
return NC_EINVAL; /* invalid base pe */
}
/* initialize common values */
ncp->lock[LOCKNUMREC_VALUE] = 0;
ncp->lock[LOCKNUMREC_LOCK] = 0;
ncp->lock[LOCKNUMREC_SERVING] = 0;
ncp->lock[LOCKNUMREC_BASEPE] = basepe;
return NC_NOERR;
}
#endif
/*
* Compute the expected size of the file.
@ -1017,11 +994,7 @@ int NC3_new_nc(NC3_INFO** ncpp)
NC *nc;
NC3_INFO* nc3;
#if _CRAYMPP && defined(LOCKNUMREC)
ncp = (NC *) shmalloc(sizeof(NC));
#else
ncp = (NC *) malloc(sizeof(NC));
#endif /* _CRAYMPP && LOCKNUMREC */
if(ncp == NULL)
return NC_ENOMEM;
(void) memset(ncp, 0, sizeof(NC));
@ -1058,20 +1031,13 @@ NC3_create(const char *path, int ioflags, size_t initialsz, int basepe,
fSet(ioflags, NC_SHARE);
#endif
#if defined(LOCKNUMREC) /* && _CRAYMPP */
if (status = NC_init_pe(nc3, basepe)) {
return status;
}
#else
/*
* !_CRAYMPP, only pe 0 is valid
* Only pe 0 is valid
*/
if(basepe != 0) {
if(nc3) free(nc3);
return NC_EINVAL;
}
#endif
if(nc3) free(nc3);
return NC_EINVAL;
}
assert(nc3->flags == 0);
/* Now we can set min size */
@ -1193,23 +1159,17 @@ NC3_open(const char *path, int ioflags, int basepe, size_t *chunksizehintp,
fSet(ioflags, NC_SHARE);
#endif
#if defined(LOCKNUMREC) /* && _CRAYMPP */
if (status = NC_init_pe(nc3, basepe)) {
goto unwind_alloc;
}
#else
/*
* !_CRAYMPP, only pe 0 is valid
* Only pe 0 is valid.
*/
if(basepe != 0) {
if(nc3) {
free(nc3);
nc3 = NULL;
}
status = NC_EINVAL;
goto unwind_alloc;
}
#endif
if(nc3) {
free(nc3);
nc3 = NULL;
}
status = NC_EINVAL;
goto unwind_alloc;
}
#ifdef ENABLE_BYTERANGE
/* If the model specified the use of byte-ranges, then signal by
@ -1577,37 +1537,6 @@ NC3_set_fill(int ncid,
return NC_NOERR;
}
#ifdef LOCKNUMREC
/* create function versions of the NC_*_numrecs macros */
size_t
NC_get_numrecs(const NC *nc3) {
shmem_t numrec;
shmem_short_get(&numrec, (shmem_t *) nc3->lock + LOCKNUMREC_VALUE, 1,
nc3->lock[LOCKNUMREC_BASEPE]);
return (size_t) numrec;
}
void
NC_set_numrecs(NC *nc3, size_t nrecs)
{
shmem_t numrec = (shmem_t) nrecs;
/* update local value too */
nc3->lock[LOCKNUMREC_VALUE] = (ushmem_t) numrec;
shmem_short_put((shmem_t *) nc3->lock + LOCKNUMREC_VALUE, &numrec, 1,
nc3->lock[LOCKNUMREC_BASEPE]);
}
void NC_increase_numrecs(NC *nc3, size_t nrecs)
{
/* this is only called in one place that's already protected
* by a lock ... so don't worry about it */
if (nrecs > NC_get_numrecs(nc3))
NC_set_numrecs(nc3, nrecs);
}
#endif /* LOCKNUMREC */
/**
* Return the file format.
*
@ -1719,7 +1648,18 @@ NC3_inq_type(int ncid, nc_type typeid, char *name, size_t *size)
return NC_NOERR;
}
/**************************************************/
/**
* This is an obsolete form of nc_delete(), supported for backwards
* compatibility.
*
* @param path Filename to delete.
* @param basepe Must be 0.
*
* @return ::NC_NOERR No error.
* @return ::NC_EIO Couldn't delete file.
* @return ::NC_EINVAL Invaliod basepe. Must be 0.
* @author Glenn Davis, Ed Hartnett
*/
int
nc_delete_mp(const char * path, int basepe)
{
@ -1733,17 +1673,11 @@ nc_delete_mp(const char * path, int basepe)
status = NC_check_id(ncid,&nc);
if(status) return status;
#if defined(LOCKNUMREC) /* && _CRAYMPP */
if (status = NC_init_pe(nc3, basepe)) {
return status;
}
#else
/*
* !_CRAYMPP, only pe 0 is valid
* Only pe 0 is valid.
*/
if(basepe != 0)
return NC_EINVAL;
#endif
(void) nc_close(ncid);
if(unlink(path) == -1) {

View File

@ -28,13 +28,6 @@ dnl
#include "ncx.h"
#include "fbits.h"
#include "onstack.h"
#ifdef LOCKNUMREC
# include <mpp/shmem.h> /* for SGI/Cray SHMEM routines */
# ifdef LN_TEST
# include <stdio.h>
# endif
#endif
#undef MIN /* system may define MIN somewhere and complain */
#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn))
@ -403,40 +396,6 @@ static int
NCvnrecs(NC3_INFO* ncp, size_t numrecs)
{
int status = NC_NOERR;
#ifdef LOCKNUMREC
ushmem_t myticket = 0, nowserving = 0;
ushmem_t numpe = (ushmem_t) _num_pes();
/* get ticket and wait */
myticket = shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_LOCK,
ncp->lock[LOCKNUMREC_BASEPE]);
#ifdef LN_TEST
fprintf(stderr,"%d of %d : ticket = %hu\n",
_my_pe(), _num_pes(), myticket);
#endif
do {
shmem_short_get((shmem_t *) &nowserving,
(shmem_t *) ncp->lock + LOCKNUMREC_SERVING, 1,
ncp->lock[LOCKNUMREC_BASEPE]);
#ifdef LN_TEST
fprintf(stderr,"%d of %d : serving = %hu\n",
_my_pe(), _num_pes(), nowserving);
#endif
/* work-around for non-unique tickets */
if (nowserving > myticket && nowserving < myticket + numpe ) {
/* get a new ticket ... you've been bypassed */
/* and handle the unlikely wrap-around effect */
myticket = shmem_short_finc(
(shmem_t *) ncp->lock + LOCKNUMREC_LOCK,
ncp->lock[LOCKNUMREC_BASEPE]);
#ifdef LN_TEST
fprintf(stderr,"%d of %d : new ticket = %hu\n",
_my_pe(), _num_pes(), myticket);
#endif
}
} while(nowserving != myticket);
/* now our turn to check & update value */
#endif
if(numrecs > NC_get_numrecs(ncp))
{
@ -519,11 +478,6 @@ NCvnrecs(NC3_INFO* ncp, size_t numrecs)
}
common_return:
#ifdef LOCKNUMREC
/* finished with our lock - increment serving number */
(void) shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_SERVING,
ncp->lock[LOCKNUMREC_BASEPE]);
#endif
return status;
}

View File

@ -244,11 +244,6 @@ main(
#endif
memset(&globalspecials,0,sizeof(GlobalSpecialData));
#if _CRAYMPP && 0
/* initialize CRAY MPP parallel-I/O library */
(void) par_io_init(32, 32);
#endif
while ((c = getopt(argc, argv, "134567bB:cdD:fhHk:l:M:no:Pv:xL:N:")) != EOF)
switch(c) {
case 'd':

View File

@ -114,11 +114,6 @@ main(
cmode_modifier = 0;
nofill_flag = 0;
#if _CRAYMPP && 0
/* initialize CRAY MPP parallel-I/O library */
(void) par_io_init(32, 32);
#endif
while ((c = getopt(argc, argv, "bcfk:l:no:v:x")) != EOF)
switch(c) {
case 'c': /* for c output, old version of "-lc" */

21
unit_test/Makefile.am Normal file
View File

@ -0,0 +1,21 @@
## This is a automake file, part of Unidata's netCDF package.
# Copyright 2019, see the COPYRIGHT file for more information.
# This file builds and runs the unit tests. These tests are not run in
# the CMake build, because we would then have to extern these internal
# functions, to allow Windows to work. Since we have not extern'd
# these functions, they will only be run under the autotools build.
# Ed Hartnett 8/9/19
# Put together AM_CPPFLAGS and AM_LDFLAGS.
include $(top_srcdir)/lib_flags.am
# Find and link to the netcdf-c library.
LDADD = ${top_builddir}/liblib/libnetcdf.la
check_PROGRAMS = tst_nclist
TESTS = tst_nclist
# If valgrind is present, add valgrind targets.
@VALGRIND_CHECK_RULES@

110
unit_test/tst_nclist.c Normal file
View File

@ -0,0 +1,110 @@
/* This is part of the netCDF package. Copyright 2005-2019 University
Corporation for Atmospheric Research/Unidata. See COPYRIGHT file
for conditions of use.
Test list functions in nclistmgr.c.
Ed Hartnett, 8/10/19
*/
#include "config.h"
#include <nc_tests.h>
#include "nc.h"
#include "ncdispatch.h"
#include "err_macros.h"
/* An integer value to use in testing. */
#define TEST_VAL_42 42
int
main(int argc, char **argv)
{
printf("\n*** Testing netcdf internal NC list functions.\n");
printf("Testing NC list functions with no open files...");
{
/* These are cases where there are no files, or NULL
* params. */
if (count_NCList()) ERR;
free_NCList();
if (find_in_NCList_by_name("nope")) ERR;
if (iterate_NCList(0, NULL)) ERR;
}
SUMMARIZE_ERR;
printf("Testing adding to NC list...");
{
int ncid;
NC *ncp, *ncp2;
int mode = 0;
NCmodel model;
char path[] = {"file.nc"};
int ret;
/* Create the NC* instance and insert its dispatcher and model. */
if ((ret = new_NC(NULL, path, mode, &model, &ncp))) ERR;
/* Nothing to find yet. */
if (find_in_NCList(TEST_VAL_42)) ERR;
/* Add to list of known open files and define ext_ncid. */
add_to_NCList(ncp);
/* These won't work! */
if (find_in_NCList(TEST_VAL_42)) ERR;
if (find_in_NCList_by_name("nope")) ERR;
if ((ret = iterate_NCList(2, &ncp2))) ERR;
/* Find it in the list. */
if (!(ncp2 = find_in_NCList(ncp->ext_ncid))) ERR;
if (!(ncp2 = find_in_NCList_by_name(path))) ERR;
if ((ret = iterate_NCList(1, &ncp2))) ERR;
if (count_NCList() != 1) ERR;
/* Won't do anything because list contains an entry. */
free_NCList();
/* Delete it. */
ncid = ncp->ext_ncid;
del_from_NCList(ncp); /* Will free empty list. */
free_NC(ncp);
if (find_in_NCList(ncid)) ERR;
}
SUMMARIZE_ERR;
#ifdef LARGE_FILE_TESTS
/* This test is slow, only run it on large file test builds. */
printf("Testing maxing out NC list...");
{
NC *ncp;
int mode = 0;
NCmodel model;
char path[] = {"file.nc"};
int max_num_nc = 65535;
int i;
int ret;
/* Fill the NC list. */
for (i = 0; i < max_num_nc; i++)
{
if ((ret = new_NC(NULL, path, mode, &model, &ncp))) ERR;
if (add_to_NCList(ncp)) ERR;
}
/* Check the count. */
if (count_NCList() != max_num_nc) ERR;
/* Try and add another. It will fail. */
if (add_to_NCList(ncp) != NC_ENOMEM) ERR;
/* Delete them all. */
for (i = 0; i < max_num_nc; i++)
{
if (iterate_NCList(i + 1, &ncp)) ERR;
if (!ncp) ERR;
del_from_NCList(ncp);
free_NC(ncp);
}
}
SUMMARIZE_ERR;
#endif /* LARGE_FILE_TESTS */
FINAL_RESULTS;
}