Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
iochunk.c
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001, Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2.1 of the GNU Lesser General Public License 
00007   as published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU Lesser General Public 
00021   License along with this program; if not, write the Free Software 
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
00023   USA.
00024 
00025   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00026   Mountain View, CA 94043, or:
00027 
00028   http://www.sgi.com
00029 
00030   For further information regarding this notice, see:
00031 
00032   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00033 
00034 */
00035 
00036 
00037 
00038 #pragma ident "@(#) libf/fio/iochunk.c  92.2    06/21/99 10:37:55"
00039 
00040  
00041 #include <liberrno.h>
00042 #include <stdlib.h>
00043 #include <cray/nassert.h>
00044 #include "fio.h"
00045 #include "f90io.h"
00046 
00047 /*
00048  *      _iochunk
00049  *
00050  *              Perform I/O on all items in an I/O list.  func may be
00051  *              _ld_read, _rdfmt, _rdunf, _ld_write, _wrfmt, or _wrunf.
00052  *      
00053  *      Return Value:
00054  *
00055  *              0               normal return
00056  *              FEEORCND        if end of record condition (with ADVANCE='NO')
00057  *              other <0        if end of file condition
00058  *              >0              if error condition
00059  */
00060 
00061 
00062 int
00063 _iochunk(
00064         FIOSPTR         css,
00065         unit            *cup,
00066         xfer_func       *func,
00067         struct DvDimen  *dim,   
00068         type_packet     *tip,   /* Type information packet */
00069         short           nd,     /* number of dimensions (must be >= 1) */
00070         long            extent, /* number of elements in first dimension */
00071         int             bshft,  /* see _stride_dv for details about bshft */
00072         bcont           *addr)  /* data pointer */
00073 
00074 {
00075         register int    errn;
00076         register long   binc;   /* stride (in bytes) passed to gather/scatter */
00077         register long   dim2_ex;
00078         register long   dim1_pb;
00079         register long   dim1_sz;
00080         register long   i;
00081         register long   id3, id4, id5, id6, id7;
00082         long            lbuf[CHBUFSIZE / sizeof(long)];
00083         char            *lptr;
00084         bcont           *addr2, *addr3, *addr4, *addr5, *addr6;
00085 
00086         /* Do not call this if dim1 does not fit in chunking buffer */
00087 
00088         assert ( (extent * tip->elsize) <= CHBUFSIZE );
00089 
00090         binc            = tip->elsize * tip->stride;    /* stride in bytes */
00091         dim1_sz         = extent * tip->elsize; /* size (bytes) of dim 1 */
00092         tip->stride     = 1;            /* linear, from here on down */
00093 
00094         if (nd == 1)
00095                 dim2_ex = 1;
00096         else
00097                 dim2_ex = dim[1].extent;
00098 
00099         dim1_pb = CHBUFSIZE / dim1_sz;  /* dim 1 extents per buffer */
00100 
00101         if (dim1_pb > dim2_ex)
00102                 dim1_pb = dim2_ex;      /* reduce to dim 2 extent */
00103 
00104         switch (nd) {
00105 
00106         case 7:
00107             for (id7 = 0; id7 < dim[6].extent; id7++) {
00108               addr6     = addr;
00109         case 6:
00110               for (id6 = 0; id6 < dim[5].extent; id6++) {
00111                 addr5   = addr;
00112         case 5:
00113                 for (id5 = 0; id5 < dim[4].extent; id5++) {
00114                   addr4 = addr;
00115         case 4:
00116                   for (id4 = 0; id4 < dim[3].extent; id4++) {
00117                     addr3       = addr;
00118         case 3:
00119                     for (id3 = 0; id3 < dim[2].extent; id3++) {
00120                       addr2     = addr;
00121 
00122         case 2:
00123                       dim2_ex   = dim[1].extent;
00124 
00125                       while (dim2_ex > 0) {
00126 
00127                         if (dim1_pb > dim2_ex)
00128                                 dim1_pb = dim2_ex;
00129                 
00130         case 1:
00131                         lptr            = (char *) lbuf;
00132                         tip->count      = dim1_pb * extent;
00133 
00134                         if (cup->uwrt) {        /* If writing */
00135 
00136                           /*
00137                            * This loop transfers 1 or more passes through
00138                            * dimension 1 to cup->ucbuf buffer.
00139                            */
00140 
00141                           for (i = 0; i < dim1_pb; i++) {
00142                             _gather_data(lptr, extent, binc, tip->elsize, addr);
00143 
00144                             addr        = addr + (dim[1].stride_mult << bshft);
00145                             lptr        = lptr + dim1_sz;
00146                           }
00147 
00148                           errn  = func(css, cup, lbuf, tip, PARTIAL);
00149                         }
00150                         else {                  /* If reading */
00151 
00152                           errn  = func(css, cup, lbuf, tip, PARTIAL);
00153 
00154                           /*
00155                            * This loop transfers 1 or more passes through
00156                            * dimension 1 from the lbuf[] buffer.
00157                            */
00158 
00159                           for (i = 0; i < dim1_pb; i++) {
00160                             _scatter_data(addr, extent, binc, tip->elsize, lptr);
00161 
00162                             addr        = addr + (dim[1].stride_mult << bshft);
00163                             lptr        = lptr + dim1_sz;
00164                           }
00165                         }
00166 
00167                         if (errn != 0) goto done;
00168 
00169                         dim2_ex = dim2_ex - dim1_pb;
00170 
00171                         if (nd == 1) goto done;
00172                       }
00173 
00174                       if (nd == 2) goto done;
00175                       addr      = addr2 + (dim[2].stride_mult << bshft);
00176                     }
00177                     if (nd == 3) goto done;
00178                     addr        = addr3 + (dim[3].stride_mult << bshft);
00179                   }
00180                   if (nd == 4) goto done;
00181                   addr  = addr4 + (dim[4].stride_mult << bshft);
00182                 }
00183                 if (nd == 5) goto done;
00184                 addr    = addr5 + (dim[5].stride_mult << bshft);
00185               }
00186               if (nd == 6) goto done;
00187               addr      = addr6 + (dim[6].stride_mult << bshft);
00188             }
00189         }
00190 
00191 done:
00192         return(errn);
00193 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines