⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ffio.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	Copyright 1996, University Corporation for Atmospheric Research *	See netcdf/COPYRIGHT file for copying and redistribution conditions. *//* $Id: ffio.c 2501 2007-11-20 02:33:29Z benkirk $ *//* addition by O. Heudecker, AWI-Bremerhaven, 12.3.1998 *//* added correction by John Sheldon and Hans Vahlenkamp 15.4.1998*/#include "ncconfig.h"#include <assert.h>#include <stdlib.h>#include <stdio.h>	/* DEBUG */#include <errno.h>#ifndef ENOERR#define ENOERR 0#endif#include <fcntl.h>#include <ffio.h>#include <unistd.h>#include <string.h>/* Insertion by O. R. Heudecker, AWI-Bremerhaven 12.3.98 (1 line)*/#include <fortran.h>#include "ncio.h"#include "fbits.h"#include "rnd.h"#if !defined(NDEBUG) && !defined(X_INT_MAX)#define  X_INT_MAX 2147483647#endif#if 0 /* !defined(NDEBUG) && !defined(X_ALIGN) */#define  X_ALIGN 4#endif#define ALWAYS_NC_SHARE 0 /* DEBUG *//* Begin OS *//* * What is the preferred I/O block size? * (This becomes the default *sizehint == ncp->chunk in the higher layers.) * TODO: What is the the best answer here? */static size_tblksize(int fd){	struct ffc_stat_s sb;	struct ffsw sw;	if (fffcntl(fd, FC_STAT, &sb, &sw) > -1)	{#ifdef __crayx1		if(sb.st_blksize > 0)			return (size_t) sb.st_blksize;#else		if(sb.st_oblksize > 0)			return (size_t) sb.st_oblksize;#endif	}	/* else, silent in the face of error */	return (size_t) 32768;}/* * Sortof like ftruncate, except won't make the * file shorter. */static intfgrow(const int fd, const off_t len){	struct ffc_stat_s sb;	struct ffsw sw;	if (fffcntl(fd, FC_STAT, &sb, &sw) < 0)		return errno;	if (len < sb.st_size)		return ENOERR;	{		const long dumb = 0;			/* cache current position */		const off_t pos = ffseek(fd, 0, SEEK_CUR);		if(pos < 0)			return errno;		if (ffseek(fd, len-sizeof(dumb), SEEK_SET) < 0)			return errno;		if(ffwrite(fd, (void *)&dumb, sizeof(dumb)) < 0)			return errno;		if (ffseek(fd, pos, SEEK_SET) < 0)			return errno;	}	/* else */	return ENOERR;}/* * Sortof like ftruncate, except won't make the file shorter.  Differs * from fgrow by only writing one byte at designated seek position, if * needed. */static intfgrow2(const int fd, const off_t len){	struct ffc_stat_s sb;	struct ffsw sw;	if (fffcntl(fd, FC_STAT, &sb, &sw) < 0)		return errno;	if (len <= sb.st_size)		return ENOERR;	{	    const char dumb = 0;	    /* we don't use ftruncate() due to problem with FAT32 file systems */	    /* cache current position */	    const off_t pos = ffseek(fd, 0, SEEK_CUR);	    if(pos < 0)		return errno;	    if (ffseek(fd, len-1, SEEK_SET) < 0)		return errno;	    if(ffwrite(fd, (void *)&dumb, sizeof(dumb)) < 0)		return errno;	    if (ffseek(fd, pos, SEEK_SET) < 0)		return errno;	}	return ENOERR;}/* End OS *//* Begin ffio */static intffio_pgout(ncio *const nciop, 	off_t const offset,  const size_t extent,	const void *const vp, off_t *posp){#ifdef X_ALIGN	assert(offset % X_ALIGN == 0);	assert(extent % X_ALIGN == 0);#endif	if(*posp != offset)	{		if(ffseek(nciop->fd, offset, SEEK_SET) != offset)		{			return errno;		}		*posp = offset;	}	if(ffwrite(nciop->fd, vp, extent) != extent)	{		return errno;	}	*posp += extent;	return ENOERR;}static intffio_pgin(ncio *const nciop,	off_t const offset, const size_t extent,	void *const vp, size_t *nreadp, off_t *posp){	int status;	ssize_t nread;#ifdef X_ALIGN	assert(offset % X_ALIGN == 0);	assert(extent % X_ALIGN == 0);#endif	if(*posp != offset)	{		if(ffseek(nciop->fd, offset, SEEK_SET) != offset)		{			status = errno;			return status;		}		*posp = offset;	}	errno = 0;	nread = ffread(nciop->fd, vp, extent);	if(nread != extent)	{		status = errno;		if(nread == -1 || status != ENOERR)			return status;		/* else it's okay we read 0. */	}	*nreadp = nread;	*posp += nread;	return ENOERR;}/* */typedef struct ncio_ffio {	off_t pos;	/* buffer */	off_t	bf_offset; 	size_t	bf_extent;	size_t	bf_cnt;	void	*bf_base;} ncio_ffio;static intncio_ffio_rel(ncio *const nciop, off_t offset, int rflags){	ncio_ffio *ffp = (ncio_ffio *)nciop->pvt;	int status = ENOERR;	assert(ffp->bf_offset <= offset);	assert(ffp->bf_cnt != 0);	assert(ffp->bf_cnt <= ffp->bf_extent);#ifdef X_ALIGN	assert(offset < ffp->bf_offset + X_ALIGN);	assert(ffp->bf_cnt % X_ALIGN == 0 );#endif	if(fIsSet(rflags, RGN_MODIFIED))	{		if(!fIsSet(nciop->ioflags, NC_WRITE))			return EPERM; /* attempt to write readonly file */		status = ffio_pgout(nciop, ffp->bf_offset,			ffp->bf_cnt,			ffp->bf_base, &ffp->pos);		/* if error, invalidate buffer anyway */	}	ffp->bf_offset = OFF_NONE;	ffp->bf_cnt = 0;	return status;}static intncio_ffio_get(ncio *const nciop,		off_t offset, size_t extent,		int rflags,		void **const vpp){	ncio_ffio *ffp = (ncio_ffio *)nciop->pvt;	int status = ENOERR;#ifdef X_ALIGN	size_t rem;#endif		if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE))		return EPERM; /* attempt to write readonly file */	assert(extent != 0);	assert(extent < X_INT_MAX); /* sanity check */	assert(ffp->bf_cnt == 0);#ifdef X_ALIGN	/* round to seekable boundaries */	rem = offset % X_ALIGN;	if(rem != 0)	{		offset -= rem;		extent += rem;	}	{		const size_t rndup = extent % X_ALIGN;		if(rndup != 0)			extent += X_ALIGN - rndup;	}	assert(offset % X_ALIGN == 0);	assert(extent % X_ALIGN == 0);#endif	if(ffp->bf_extent < extent)	{		if(ffp->bf_base != NULL)		{			free(ffp->bf_base);			ffp->bf_base = NULL;			ffp->bf_extent = 0;		}		assert(ffp->bf_extent == 0);		ffp->bf_base = malloc(extent);		if(ffp->bf_base == NULL)			return ENOMEM;		ffp->bf_extent = extent;	}	status = ffio_pgin(nciop, offset,		 extent,		 ffp->bf_base,		 &ffp->bf_cnt, &ffp->pos);	if(status != ENOERR)		return status;	ffp->bf_offset = offset;	if(ffp->bf_cnt < extent)	{		(void) memset((char *)ffp->bf_base + ffp->bf_cnt, 0,			extent - ffp->bf_cnt);		ffp->bf_cnt = extent;	}#ifdef X_ALIGN	*vpp = (char *)ffp->bf_base + rem;#else	*vpp = (char *)ffp->bf_base;#endif	return ENOERR;}static intncio_ffio_move(ncio *const nciop, off_t to, off_t from,			size_t nbytes, int rflags){	int status = ENOERR;	off_t lower = from;		off_t upper = to;	char *base;	size_t diff = upper - lower;	size_t extent = diff + nbytes;	rflags &= RGN_NOLOCK; /* filter unwanted flags */	if(to == from)		return ENOERR; /* NOOP */		if(to > from)	{		/* growing */		lower = from;			upper = to;	}	else	{		/* shrinking */		lower = to;		upper = from;	}	diff = upper - lower;	extent = diff + nbytes;	status = ncio_ffio_get(nciop, lower, extent, RGN_WRITE|rflags,			(void **)&base);	if(status != ENOERR)		return status;	if(to > from)		(void) memmove(base + diff, base, nbytes); 	else		(void) memmove(base, base + diff, nbytes); 			(void) ncio_ffio_rel(nciop, lower, RGN_MODIFIED);	return status;}#ifdef NOFFFLUSH/* ncio_ffio_sync_noffflush is only needed if the FFIO global layer is * used, because it currently has a bug that causes the PEs to hang * RKO 06/26/98 */static intncio_ffio_sync_noffflush(ncio *const nciop){	struct ffc_stat_s si;	/* for call to fffcntl() */	struct ffsw ffstatus;	/* to return ffsw.sw_error */	/* run some innocuous ffio routine to get if any errno */	if(fffcntl(nciop->fd, FC_STAT, &si, &ffstatus) < 0)		return ffstatus.sw_error;	return ENOERR;}/* this tests to see if the global FFIO layer is being called for * returns ~0 if it is, else returns 0 */static intncio_ffio_global_test(const char *ControlString){	if (strstr(ControlString,"global") != (char *) NULL) {		return ~0;	} else {		return 0;	}}#endifstatic intncio_ffio_sync(ncio *const nciop){#ifdef __crayx1	struct ffsw stat;	if(ffflush(nciop->fd,&stat) < 0)#else	if(ffflush(nciop->fd) < 0)#endif		return errno;	return ENOERR;}static voidncio_ffio_free(void *const pvt){	ncio_ffio *ffp = (ncio_ffio *)pvt;	if(ffp == NULL)		return;	if(ffp->bf_base != NULL)	{		free(ffp->bf_base);		ffp->bf_base = NULL;		ffp->bf_offset = OFF_NONE;		ffp->bf_extent = 0;		ffp->bf_cnt = 0;	}}static intncio_ffio_init2(ncio *const nciop, size_t *sizehintp){	ncio_ffio *ffp = (ncio_ffio *)nciop->pvt;	assert(nciop->fd >= 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -