Пример #1
0
int
_iochunk(
	FIOSPTR		css,
	unit		*cup,
	xfer_func	*func,
	struct DvDimen	*dim,	
	type_packet	*tip,	/* Type information packet */
	short		nd,	/* number of dimensions (must be >= 1) */
	long		extent,	/* number of elements in first dimension */
	int		bshft,	/* see _stride_dv for details about bshft */
	bcont		*addr)	/* data pointer */

{
	register int	errn;
	register long	binc;	/* stride (in bytes) passed to gather/scatter */
	register long	dim2_ex;
	register long	dim1_pb;
	register long	dim1_sz;
	register long	i;
	register long	id3, id4, id5, id6, id7;
#ifdef KEY
	/* align lbuf on 64-bit boundary */
	long long	lbuf[CHBUFSIZE / sizeof(long long)];
#else
	long		lbuf[CHBUFSIZE / sizeof(long)];
#endif
	char		*lptr;
	bcont		*addr2, *addr3, *addr4, *addr5, *addr6;

	/* Do not call this if dim1 does not fit in chunking buffer */

	assert ( (extent * tip->elsize) <= CHBUFSIZE );

	binc		= tip->elsize * tip->stride;	/* stride in bytes */
	dim1_sz		= extent * tip->elsize;	/* size (bytes) of dim 1 */
	tip->stride	= 1;		/* linear, from here on down */

	if (nd == 1)
		dim2_ex	= 1;
	else
		dim2_ex	= dim[1].extent;

	dim1_pb	= CHBUFSIZE / dim1_sz;	/* dim 1 extents per buffer */

	if (dim1_pb > dim2_ex)
		dim1_pb	= dim2_ex;	/* reduce to dim 2 extent */

	switch (nd) {

	case 7:
	    for (id7 = 0; id7 < dim[6].extent; id7++) {
	      addr6	= addr;
	case 6:
	      for (id6 = 0; id6 < dim[5].extent; id6++) {
	        addr5	= addr;
	case 5:
		for (id5 = 0; id5 < dim[4].extent; id5++) {
	          addr4	= addr;
	case 4:
		  for (id4 = 0; id4 < dim[3].extent; id4++) {
		    addr3	= addr;
	case 3:
		    for (id3 = 0; id3 < dim[2].extent; id3++) {
		      addr2	= addr;

	case 2:
		      dim2_ex	= dim[1].extent;

		      while (dim2_ex > 0) {

			if (dim1_pb > dim2_ex)
				dim1_pb	= dim2_ex;
		
	case 1:
			lptr		= (char *) lbuf;
			tip->count	= dim1_pb * extent;

			if (cup->uwrt) {	/* If writing */

			  /*
			   * This loop transfers 1 or more passes through
			   * dimension 1 to cup->ucbuf buffer.
			   */

			  for (i = 0; i < dim1_pb; i++) {
			    _gather_data(lptr, extent, binc, tip->elsize, addr);

	      	            addr	= addr + (dim[1].stride_mult << bshft);
	      	            lptr	= lptr + dim1_sz;
			  }

			  errn	= func(css, cup, lbuf, tip, PARTIAL);
			}
			else {			/* If reading */

			  errn	= func(css, cup, lbuf, tip, PARTIAL);

			  /*
			   * This loop transfers 1 or more passes through
			   * dimension 1 from the lbuf[] buffer.
			   */

			  for (i = 0; i < dim1_pb; i++) {
			    _scatter_data(addr, extent, binc, tip->elsize, lptr);

	      	            addr	= addr + (dim[1].stride_mult << bshft);
	      	            lptr	= lptr + dim1_sz;
			  }
			}

			if (errn != 0) goto done;

			dim2_ex	= dim2_ex - dim1_pb;

		        if (nd == 1) goto done;
		      }

		      if (nd == 2) goto done;
	      	      addr	= addr2 + (dim[2].stride_mult << bshft);
		    }
		    if (nd == 3) goto done;
	      	    addr	= addr3 + (dim[3].stride_mult << bshft);
		  }
		  if (nd == 4) goto done;
	      	  addr	= addr4 + (dim[4].stride_mult << bshft);
		}
		if (nd == 5) goto done;
	      	addr	= addr5 + (dim[5].stride_mult << bshft);
	      }
	      if (nd == 6) goto done;
	      addr	= addr6 + (dim[6].stride_mult << bshft);
	    }
	}

done:
	return(errn);
}
Пример #2
0
int
_wrunf(
#endif
	FIOSPTR		css,	/* Current Fortran I/O statement state */
	unit		*cup,	/* Unit pointer */
	void		*ptr,	/* Pointer to data */
	type_packet	*tip,	/* Type information packet */
	int		mode	/* Mode argument to _fwwd() */
)
{
	register short	shared;		/* 1 iff ptr points to sdd */
	register int	errn;		/* Error number */
	register int64	fillen;		/* bit size of each element, on disk */
	register long	count;		/* Number of data items */
	register long	elsize;		/* element size in bytes */
	register long	i;
	register long	incb;		/* inc (in units of bytes) */
	register long	items;
	long		lbuf[LOCBUFLN]; 
	void		*fwwdbuf;	/* ptr to buffer passed to _fwwd */
#ifdef	_CRAYT3D
	register long	elwords;	/* element size in words */
#endif

	errn	= 0;
	shared	= 0;
	count	= tip->count;
	elsize	= tip->elsize;
	fillen	= tip->extlen;

	if (count == 0)
		return(0);

	if (tip->type90 == DVTYPE_ASCII)
		fillen	= fillen * elsize;

	incb	= tip->stride * elsize;	/* Stride in bytes */

	if (cup->useq == 0) {	/* If direct access file */
		register int64	newpos;
		register int64	recl;

		newpos	= cup->urecpos + count * fillen; /* in bits */
		recl	= (int64) (cup->urecl);

		if ((recl << 3) < newpos) {
			errn	= FEWRLONG;	/* output record too long */
			goto done;
		}
	}

#ifdef	_CRAYT3D
	if (_issddptr(ptr)) {
		/* ptr points to a shared data descriptor */
		/* If we have a layer that handles sdds someday, we */
		/* could check for that here and not set shared to one. */
		/* We'd also probably want to make sure that we're not */
		/* doing foreign data converion */
		shared	= 1;
		elwords	= elsize / sizeof(long);
	}
#endif

/*
 *	If only one item, or stride is such that data is contiguous,
 *	do it all at once
 */
	if ((shared == 0) && ((count == 1) || (incb == elsize))) {
		register long	ret;
		int		status;

		if (mode == FULL)
			cup->f_lastwritten = 1;

		ret	= _fwwd(cup, ptr, tip, mode, (int *) NULL,
				(long *) NULL, &status);

		if ( ret == IOERR ) {
			errn	= errno;
			goto done;
		}

		return(0);
	}

/*
 *	Stride is such that memory is not contiguous, break the request
 *	into chunks and do a gaterh on the items before writing.
 */

	items	= (LOCBUFLN * sizeof(long)) / elsize;	/* chop it in chunks */

	assert( ! (shared && items == 0) );	/* don't support shared char */

	if (items == 0)
		items	= 1;			/* must be character*BIG array*/

	fwwdbuf	= lbuf;

	for ( i = 0; i < count; i = i + items ) {
		register long	ret;
		int		status;

		/* trim the item count if not a full buffer's worth */

		if (items > count - i)
			items	= count - i;

		tip->count	= items;

		/*
		 * Gather items from user array into lbuf, and then write
		 * out a chunk.  If items == 1, we suppress the extra data
		 * copy for performance and because it might not fit in the
		 * lbuf if it is character*BIG data.
		 *
	 	 * We don't have to worry about shared data not fitting 
		 * in lbuf since character data is never shared.
		 */ 

#ifdef	_CRAYT3D
		if (shared)
			_cpyfrmsdd(ptr, lbuf, items, elwords, tip->stride, i);
		else
#endif
		{
			if (items > 1) 
				_gather_data (lbuf, items, incb, elsize, ptr);
			else 
				fwwdbuf	= ptr;
		
		}

		if ( mode == FULL && (i+items >= count)) {
			cup->f_lastwritten = 1;
			ret	= _fwwd(cup, fwwdbuf, tip, FULL, (int *) NULL,
					(long *) NULL, &status);
		}
		else
			ret	= _fwwd(cup, fwwdbuf, tip, PARTIAL,
					(int *) NULL, (long *) NULL, &status);

		if ( ret == IOERR ) {
			errn	= errno; 
			goto done;
		}

		if (!shared)
			ptr	= (char *)ptr + (ret * incb);
	}

done:
	if (errn > 0) {
		if ((cup->uflag & (_UERRF | _UIOSTF)) == 0)
			_ferr(css, errn);	/* Run-time error */
	}
		
	return(errn);
}