Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
wb.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/wb.c       92.3    06/21/99 10:37:55"
00039 
00040 #include <errno.h>
00041 #include <liberrno.h>
00042 #include <fortran.h>
00043 #include <cray/nassert.h>
00044 #ifdef  _CRAYT3D
00045 #include <cray/mppsdd.h>
00046 #endif
00047 #include "fio.h"
00048 #include "f90io.h"
00049 
00050 static void
00051 _wb( FIOSPTR css, unit *cup, _f_int *recmode, gfptr_t bloc, gfptr_t eloc,
00052         type_packet *tip);
00053 
00054 #ifdef  _CRAYT3D
00055 #define MAXSH           4096
00056 #else
00057 #define MAXSH           1
00058 #endif
00059 
00060 #ifdef  _UNICOS
00061 /*
00062  *      $WB$    CFT77 BUFFER OUT wrapper
00063  */
00064 
00065 void
00066 $WB$(
00067         _f_int  *biunit,        /* Unit                 */
00068         _f_int  *recmode,       /* Mode                 */
00069         gfptr_t bloc,           /* Beginning location   */
00070         gfptr_t eloc,           /* Ending location      */
00071         int     *typep)         /* Data type            */
00072 {
00073         register short  type77;
00074         register unum_t unum;
00075         type_packet     tip;
00076         struct f90_type ts;
00077         unit            *cup;
00078         struct fiostate cfs;
00079 
00080         unum    = *biunit;
00081 
00082         STMT_BEGIN(unum, 0, T_BUFOUT, NULL, &cfs, cup);
00083 /*
00084  *      If not connected, do an implicit open.  Abort if the open fails.
00085  */
00086         if (cup == NULL)
00087                 cup     = _imp_open77(&cfs, SEQ, UNF, unum, 0, NULL);
00088 
00089         type77          = *typep & 017;
00090 
00091         CREATE_F90_INFO(ts, tip, type77);
00092 
00093 #if     NUMERIC_DATA_CONVERSION_ENABLED
00094 
00095         if (cup->unumcvrt || cup->ucharset) {
00096                 register int    ret;
00097 
00098                 ret     = _get_dc_param(&cfs, cup, ts, &tip);
00099 
00100                 if (ret != 0)
00101                         _ferr(&cfs, ret);
00102         }
00103 
00104 #endif
00105 
00106 _PRAGMA_INLINE(_wb)
00107         _wb(&cfs, cup, recmode, bloc, eloc, &tip);
00108 
00109         return;
00110 }
00111 #endif  /* _UNICOS */
00112 
00113 /*
00114  *      _BUFFEROUT      f90 BUFFER OUT wrapper
00115  */
00116 void
00117 _BUFFEROUT(struct bio_spec_list *bosl)
00118 {
00119         register unum_t unum;
00120         type_packet     tip;
00121         struct f90_type ts;
00122         unit            *cup;
00123         struct fiostate cfs;
00124 
00125         unum    = *bosl->unit;
00126         ts      = *bosl->tiptr;
00127 
00128         STMT_BEGIN(unum, 0, T_BUFOUT, NULL, &cfs, cup);
00129 /*
00130  *      If not connected, do an implicit open.
00131  */
00132         if (cup == NULL)
00133                 cup     = _imp_open(&cfs, SEQ, UNF, unum, 0, NULL);
00134 
00135         tip.type77      = -1;
00136         tip.type90      = ts.type;
00137         tip.intlen      = ts.int_len;
00138         tip.extlen      = ts.int_len;
00139         tip.elsize      = ts.int_len >> 3;
00140         tip.stride      = 1;
00141 
00142 #if     NUMERIC_DATA_CONVERSION_ENABLED
00143 
00144         if (cup->unumcvrt || cup->ucharset) {
00145                 register int    ret;
00146 
00147                 ret     = _get_dc_param(&cfs, cup, ts, &tip);
00148 
00149                 if (ret != 0)
00150                         _ferr(&cfs, ret);
00151         }
00152 
00153 #endif
00154 
00155 _PRAGMA_INLINE(_wb)
00156         _wb(    &cfs, cup, bosl->recmode, bosl->bloc, bosl->eloc, &tip);
00157 
00158         return;
00159 }
00160 
00161 /*
00162  *      _WB     "Old" f90 BUFFER OUT wrapper (not used by f90 2.0 and
00163  *              later compilers).  This routine can be deprecated one
00164  *              of these millenia.
00165  */
00166 void
00167 _WB(
00168         _f_int          *biunit,        /* Unit                 */
00169         _f_int          *recmode,       /* Mode                 */
00170         gfptr_t         bloc,           /* Beginning location   */
00171         gfptr_t         eloc,           /* Ending location      */
00172         f90_type_t      *tiptr)         /* Data type word       */
00173 {
00174         struct bio_spec_list    bsl;
00175 
00176         bsl.version     = 0;
00177         bsl.unit        = biunit;
00178         bsl.recmode     = recmode;
00179         bsl.bloc        = bloc;
00180         bsl.eloc        = eloc;
00181         bsl.tiptr       = tiptr;
00182 
00183         _BUFFEROUT(&bsl);
00184 
00185         return;
00186 }
00187 
00188 static void
00189 _wb(
00190         FIOSPTR         css,            /* Current Fortran I/O state    */
00191         unit            *cup,           /* Unit pointer                 */
00192         _f_int          *recmode,       /* Mode                         */
00193         gfptr_t         bloc,           /* Beginning location           */
00194         gfptr_t         eloc,           /* Ending location              */
00195         type_packet     *tip)           /* Type information packet      */
00196 {
00197         register int    bytshft;
00198         register int    mode;
00199         register long   bytes;
00200         register long   elsize;
00201         register long   itemlen;
00202         register long   items;
00203         register long   stat;
00204         register ftype_t type90;
00205         char            *uda, *udax;
00206 #ifdef  _CRAYT3D
00207         register short  shared;
00208         register long   ntot;
00209         register long   numleft;
00210         long            shrd[MAXSH];
00211 #endif
00212 
00213         if (cup->useq == 0)     /* If direct access file */
00214                 _ferr(css, FEBIONDA, "BUFFER OUT");
00215 
00216         if (cup->ufmt)          /* If formatted file */
00217                 _ferr(css, FEBIONFM, "BUFFER OUT");
00218 
00219         if ((cup->uerr) && (!cup->unitchk))
00220                 _ferr(css, cup->uffsw.sw_error);
00221 
00222         cup->uerr       = 0;
00223         elsize          = tip->elsize;  /* Data size in bytes */
00224         type90          = tip->type90;
00225 
00226 /*
00227  *      Set the word count, item count, and shift depending on the data type.
00228  */
00229         bytshft = ((sizeof(elsize) << 3) - 1) - _leadz(elsize); /* log2(elsize) */
00230 
00231         if (type90 == DVTYPE_ASCII) {   /* If character item */
00232                 uda     = _fcdtocp(bloc.fcd);
00233                 udax    = _fcdtocp(eloc.fcd);
00234                 itemlen = _fcdlen (eloc.fcd);
00235         }
00236         else {
00237 #ifdef  _CRAYT3D
00238                 shared  = 0;
00239 
00240                 if (_issddptr(bloc.v)) {
00241                         int     *tmpptr;
00242 
00243                         /* Shared data */
00244 
00245                         if (!_issddptr(eloc.v)) {
00246                                 _ferr(css, FEINTUNK);
00247                         }
00248 
00249                         shared  = 1;
00250                         ntot    = 0;
00251 
00252                         if ((cup->ufs == FS_FDC) &&
00253                                 (cup->uflagword & FFC_ASYNC)) {
00254                                         /* When we can do I/O from shared */
00255                                         /* memory, we can support this. */
00256                                         _ferr(css, FESHRSUP);
00257                         }
00258                         /* When compiler spr 76429 is closed, we can
00259                          * try replacing the lines that use tmpptr with this:
00260                          * items = _sdd_read_offset((void *)eloc.v) -
00261                          *       _sdd_read_offset((void *)uda + 1;
00262                          */
00263                         uda     = bloc.v;
00264                         udax    = eloc.v;
00265                         tmpptr  = (int *)((int)udax & 0xfffffffffffffff);
00266                         items   = *(tmpptr + 1);
00267                         tmpptr  = (int *)((int)uda & 0xfffffffffffffff);
00268                         items   = items - *(tmpptr + 1) + 1;
00269                 }
00270                 else 
00271 #endif  /* _CRAYT3D */
00272                 {
00273                         uda     = bloc.v;
00274                         udax    = eloc.v;
00275                 }
00276 
00277                 itemlen = elsize;
00278         }
00279 
00280 #ifdef  _CRAYT3D
00281         if (shared) {
00282                 bytes   = items << bytshft;
00283         }
00284         else
00285 #endif
00286         {
00287                 bytes   = (udax - uda) + itemlen;
00288                 items   = bytes >> bytshft;
00289         }
00290 
00291         if (bytes < 0)
00292                 _ferr(css, FEBIOFWA, "BUFFER OUT");
00293 
00294         mode            = (*recmode < 0) ? PARTIAL : FULL;
00295         cup->urecmode   = mode;
00296         cup->uwrt       = 1;
00297 
00298         if (cup->uend) {
00299                 /*
00300                  * If positioned after an endfile, and the file does not
00301                  * support multiple endfiles, a write is invalid.
00302                  */
00303                 if (!cup->umultfil && !cup->uspcproc) {
00304                         cup->uerr               = 1;
00305                         cup->uffsw.sw_error     = FEWRAFEN;
00306                         goto badpart;
00307                 }
00308                 /*
00309                  * If a logical endfile record had just been read,
00310                  * replace it with a physical endfile record before
00311                  * starting the current data record.
00312                  */
00313                 if ((cup->uend == LOGICAL_ENDFILE) && !(cup->uspcproc)) {
00314                         if (XRCALL(cup->ufp.fdc, weofrtn)cup->ufp.fdc,
00315                                 &cup->uffsw) < 0){
00316                                 cup->uerr       = 1;
00317                                 goto badpart;
00318                         }
00319                 }
00320                 cup->uend       = BEFORE_ENDFILE;
00321         }
00322 
00323         if (items << bytshft != bytes)
00324                 _ferr(css, FEBIOFWD);
00325 
00326 #ifdef  _CRAYT3D
00327         if ( !shared && cup->uasync != 0) {
00328 #else
00329         if (cup->uasync != 0) {
00330 #endif
00331                 int     ubc = 0;
00332 
00333                 WAITIO(cup, _ferr(css, cup->uffsw.sw_error));
00334 
00335 #if     defined(_UNICOS) || defined(NUMERIC_DATA_CONVERSION_ENABLED)
00336 /*
00337  *              Pad word-aligned numeric data on word boundaries within
00338  *              the record for CRI and some foreign data formats. 
00339  */
00340                 if ((cup->urecpos & cup->ualignmask) != 0 &&
00341                     type90 != DVTYPE_ASCII && 
00342                     elsize > 4 ) {
00343                         int             padubc;
00344                         register int    pbytes;
00345                         int             padval;
00346 
00347                         COMPADD(cup, pbytes, padubc, padval);
00348 
00349                         if (pbytes != 0) {
00350                                 stat    = XRCALL(cup->ufp.fdc, writertn)
00351                                                 cup->ufp.fdc,
00352                                                 WPTR2BP(&padval),
00353                                                 pbytes,
00354                                                 &cup->uffsw,
00355                                                 PARTIAL,
00356                                                 &padubc);
00357                                 if (stat != pbytes) {
00358                                         cup->uerr       = 1;
00359                                         goto badpart;
00360                                 }
00361 
00362                                 cup->urecpos    += (stat << 3) - padubc;
00363                         }
00364                 }
00365 #endif  /* NUMERIC_DATA_CONVERSION_ENABLED */
00366 
00367                 CLRSTAT(cup->uffsw);            /* clear status word */
00368                 FFSTAT(cup->uffsw)      = 0;    /* flag no status */
00369 
00370                 stat    = XRCALL(cup->ufp.fdc, writeartn) cup->ufp.fdc,
00371                                         CPTR2BP(uda),
00372                                         bytes,
00373                                         &cup->uffsw,
00374                                         mode,
00375                                         &ubc);
00376 
00377                 cup->uasync     = ASYNC_ACTIVE; /* flag last op was async */
00378 
00379                 if (stat < 0)
00380                         cup->uerr       = 1;
00381         }
00382         else {
00383                 int             dumstat;
00384 #ifdef  _CRAYT3D
00385                 register long   chunk;
00386 
00387                 if (shared) {
00388                         chunk   = (MAXSH / elsize) * sizeof(long);
00389                         uda     = (char *)shrd;
00390                         numleft = items;
00391                 }
00392                 do {
00393                         if (shared) {
00394                                 items   = MIN(chunk, numleft);
00395 
00396                                 _cpyfrmsdd(bloc.v, (long *)uda, items,
00397                                         elsize / sizeof(long), 1, ntot);
00398 
00399                                 numleft = numleft - items;
00400 
00401                                 if (numleft == 0)
00402                                         mode    = cup->urecmode;
00403                                 else
00404                                         mode    = PARTIAL;
00405                         }
00406 #endif
00407 
00408                         tip->count      = items;
00409 
00410                         stat    = _fwwd(cup, uda, tip, mode, (int *) NULL,
00411                                         (long *) NULL, &dumstat);
00412 
00413 #ifdef  _CRAYT3D
00414                         ntot    = ntot + stat;
00415                         
00416                 } while (shared && (stat == items) && (numleft > 0));
00417 #endif
00418 
00419                 if ( stat == IOERR ) {
00420                         cup->uerr               = 1;
00421                         cup->uffsw.sw_error     = errno;
00422                 }
00423 
00424 /*
00425  *              Set ulrecl to returned value -> bits
00426  */
00427 #ifdef  _CRAYT3D
00428                 if (shared)
00429                         cup->ulrecl     = ntot << (bytshft + 3);
00430                 else
00431 #endif
00432                         cup->ulrecl     = stat << (bytshft + 3);
00433 
00434         }
00435 /*
00436  *      If end of record, clear ulastyp to avoid padd
00437  */
00438         cup->ulastyp    = type90;
00439 
00440         if (cup->urecmode == FULL) {
00441 badpart:
00442                 cup->ulastyp    = DVTYPE_TYPELESS;
00443                 cup->urecpos    = 0;
00444         }
00445 
00446         STMT_END(cup, T_BUFOUT, NULL, css);
00447 
00448         return;
00449 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines