Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
wrunf.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 #ifndef INLINE
00039 #pragma ident "@(#) libf/fio/wrunf.c    92.2    06/21/99 10:37:55"
00040 #endif
00041 
00042 #include <errno.h>
00043 #include <liberrno.h>
00044 #include <fortran.h>
00045 #include <cray/nassert.h>
00046 #ifdef  _CRAYT3D
00047 #include <cray/mppsdd.h>
00048 #endif
00049 #include "fio.h"
00050 #include "f90io.h"
00051 
00052 #define LOCBUFLN 4096
00053 
00054 /*
00055  *      _wrunf()        Write unformatted processing.
00056  *
00057  *      Return value
00058  *
00059  *               0      normal return.
00060  *
00061  *              >0      if error condition and IOSTAT= or ERR= is
00062  *                      specified.
00063  */
00064 
00065 #ifdef  INLINE
00066 static int
00067 _inline_wrunf(
00068 #else
00069 int
00070 _wrunf(
00071 #endif
00072         FIOSPTR         css,    /* Current Fortran I/O statement state */
00073         unit            *cup,   /* Unit pointer */
00074         void            *ptr,   /* Pointer to data */
00075         type_packet     *tip,   /* Type information packet */
00076         int             mode    /* Mode argument to _fwwd() */
00077 )
00078 {
00079         register short  shared;         /* 1 iff ptr points to sdd */
00080         register int    errn;           /* Error number */
00081         register int64  fillen;         /* bit size of each element, on disk */
00082         register long   count;          /* Number of data items */
00083         register long   elsize;         /* element size in bytes */
00084         register long   i;
00085         register long   incb;           /* inc (in units of bytes) */
00086         register long   items;
00087         long            lbuf[LOCBUFLN]; 
00088         void            *fwwdbuf;       /* ptr to buffer passed to _fwwd */
00089 #ifdef  _CRAYT3D
00090         register long   elwords;        /* element size in words */
00091 #endif
00092 
00093         errn    = 0;
00094         shared  = 0;
00095         count   = tip->count;
00096         elsize  = tip->elsize;
00097         fillen  = tip->extlen;
00098 
00099         if (count == 0)
00100                 return(0);
00101 
00102         if (tip->type90 == DVTYPE_ASCII)
00103                 fillen  = fillen * elsize;
00104 
00105         incb    = tip->stride * elsize; /* Stride in bytes */
00106 
00107         if (cup->useq == 0) {   /* If direct access file */
00108                 register int64  newpos;
00109                 register int64  recl;
00110 
00111                 newpos  = cup->urecpos + count * fillen; /* in bits */
00112                 recl    = (int64) (cup->urecl);
00113 
00114                 if ((recl << 3) < newpos) {
00115                         errn    = FEWRLONG;     /* output record too long */
00116                         goto done;
00117                 }
00118         }
00119 
00120 #ifdef  _CRAYT3D
00121         if (_issddptr(ptr)) {
00122                 /* ptr points to a shared data descriptor */
00123                 /* If we have a layer that handles sdds someday, we */
00124                 /* could check for that here and not set shared to one. */
00125                 /* We'd also probably want to make sure that we're not */
00126                 /* doing foreign data converion */
00127                 shared  = 1;
00128                 elwords = elsize / sizeof(long);
00129         }
00130 #endif
00131 
00132 /*
00133  *      If only one item, or stride is such that data is contiguous,
00134  *      do it all at once
00135  */
00136         if ((shared == 0) && ((count == 1) || (incb == elsize))) {
00137                 register long   ret;
00138                 int             status;
00139 
00140                 if (mode == FULL)
00141                         cup->f_lastwritten = 1;
00142 
00143                 ret     = _fwwd(cup, ptr, tip, mode, (int *) NULL,
00144                                 (long *) NULL, &status);
00145 
00146                 if ( ret == IOERR ) {
00147                         errn    = errno;
00148                         goto done;
00149                 }
00150 
00151                 return(0);
00152         }
00153 
00154 /*
00155  *      Stride is such that memory is not contiguous, break the request
00156  *      into chunks and do a gaterh on the items before writing.
00157  */
00158 
00159         items   = (LOCBUFLN * sizeof(long)) / elsize;   /* chop it in chunks */
00160 
00161         assert( ! (shared && items == 0) );     /* don't support shared char */
00162 
00163         if (items == 0)
00164                 items   = 1;                    /* must be character*BIG array*/
00165 
00166         fwwdbuf = lbuf;
00167 
00168         for ( i = 0; i < count; i = i + items ) {
00169                 register long   ret;
00170                 int             status;
00171 
00172                 /* trim the item count if not a full buffer's worth */
00173 
00174                 if (items > count - i)
00175                         items   = count - i;
00176 
00177                 tip->count      = items;
00178 
00179                 /*
00180                  * Gather items from user array into lbuf, and then write
00181                  * out a chunk.  If items == 1, we suppress the extra data
00182                  * copy for performance and because it might not fit in the
00183                  * lbuf if it is character*BIG data.
00184                  *
00185                  * We don't have to worry about shared data not fitting 
00186                  * in lbuf since character data is never shared.
00187                  */ 
00188 
00189 #ifdef  _CRAYT3D
00190                 if (shared)
00191                         _cpyfrmsdd(ptr, lbuf, items, elwords, tip->stride, i);
00192                 else
00193 #endif
00194                 {
00195                         if (items > 1) 
00196                                 _gather_data (lbuf, items, incb, elsize, ptr);
00197                         else 
00198                                 fwwdbuf = ptr;
00199                 
00200                 }
00201 
00202                 if ( mode == FULL && (i+items >= count)) {
00203                         cup->f_lastwritten = 1;
00204                         ret     = _fwwd(cup, fwwdbuf, tip, FULL, (int *) NULL,
00205                                         (long *) NULL, &status);
00206                 }
00207                 else
00208                         ret     = _fwwd(cup, fwwdbuf, tip, PARTIAL,
00209                                         (int *) NULL, (long *) NULL, &status);
00210 
00211                 if ( ret == IOERR ) {
00212                         errn    = errno; 
00213                         goto done;
00214                 }
00215 
00216                 if (!shared)
00217                         ptr     = (char *)ptr + (ret * incb);
00218         }
00219 
00220 done:
00221         if (errn > 0) {
00222                 if ((cup->uflag & (_UERRF | _UIOSTF)) == 0)
00223                         _ferr(css, errn);       /* Run-time error */
00224         }
00225                 
00226         return(errn);
00227 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines