Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
rb.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/rb.c       92.2    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 _rb(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  *      $RB$    CFT77 BUFFER IN wrapper
00063  */
00064 
00065 void
00066 $RB$(
00067         _f_int  *biunit,        /* Unit                 */
00068         _f_int  *recmode,       /* Mode                 */
00069         gfptr_t bloc,           /* Beginning location   */
00070         gfptr_t eloc,           /* Ending location      */
00071         int     *type)          /* 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_BUFIN, 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          = *type & 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(_rb)
00107         _rb(&cfs, cup, recmode, bloc, eloc, &tip);
00108 
00109         return;
00110 }
00111 #endif  /* _UNICOS */
00112 
00113 /*
00114  *      _BUFFERIN       f90 BUFFER IN wrapper (also a headache remedy)
00115  */
00116 void
00117 _BUFFERIN(struct bio_spec_list *bisl)
00118 {
00119         register unum_t unum;
00120         type_packet     tip;
00121         struct f90_type ts;
00122         unit            *cup;
00123         struct fiostate cfs;
00124 
00125         assert ( bisl->version == 0 );
00126 
00127         unum    = *bisl->unit;
00128         ts      = *bisl->tiptr;
00129 
00130         STMT_BEGIN(unum, 0, T_BUFIN, NULL, &cfs, cup);
00131 /*
00132  *      If not connected, do an implicit open.  Abort if the open fails.
00133  */
00134         if (cup == NULL)
00135                 cup     = _imp_open(&cfs, SEQ, UNF, unum, 0, NULL); 
00136 
00137         tip.type77      = -1;
00138         tip.type90      = ts.type;
00139         tip.intlen      = ts.int_len;
00140         tip.extlen      = ts.int_len;
00141         tip.elsize      = ts.int_len >> 3;
00142         tip.stride      = 1;
00143 
00144 #if     NUMERIC_DATA_CONVERSION_ENABLED
00145 
00146         if (cup->unumcvrt || cup->ucharset) {
00147                 register int    ret;
00148 
00149                 ret     = _get_dc_param(&cfs, cup, ts, &tip);
00150 
00151                 if (ret != 0)
00152                         _ferr(&cfs, ret);
00153         }
00154 
00155 #endif
00156 
00157 _PRAGMA_INLINE(_rb);
00158         _rb(    &cfs, cup, bisl->recmode, bisl->bloc, bisl->eloc, &tip);
00159 
00160         return;
00161 }
00162 
00163 /*
00164  *      _RB     "Old" f90 BUFFER IN wrapper (not used by f90 2.0 and
00165  *              later compilers).  This routine can be deprecated one
00166  *              of these millenia.
00167  */
00168 void
00169 _RB(
00170         _f_int          *biunit,        /* Unit                 */
00171         _f_int          *recmode,       /* Mode                 */
00172         gfptr_t         bloc,           /* Beginning location   */
00173         gfptr_t         eloc,           /* Ending location      */
00174         f90_type_t      *tiptr)         /* Data type word       */
00175 {
00176         struct bio_spec_list    bsl;
00177 
00178         bsl.version     = 0;
00179         bsl.unit        = biunit;
00180         bsl.recmode     = recmode;
00181         bsl.bloc        = bloc;
00182         bsl.eloc        = eloc;
00183         bsl.tiptr       = tiptr;
00184 
00185         _BUFFERIN(&bsl);
00186 
00187         return;
00188 }
00189 
00190 static void 
00191 _rb(
00192         FIOSPTR         css,            /* Current Fortran I/O state    */
00193         unit            *cup,           /* Unit pointer                 */
00194         _f_int          *recmode,       /* Mode                         */
00195         gfptr_t         bloc,           /* Beginning location           */
00196         gfptr_t         eloc,           /* Ending location              */
00197         type_packet     *tip)           /* Type information packet      */
00198 {
00199         register int    bytshft;
00200         register int    mode;
00201         register long   bytes;
00202         register long   elsize;
00203         register long   itemlen;
00204         register long   items;
00205         register long   stat;
00206         register ftype_t type90;
00207         int             state;
00208         char            *uda, *udax;
00209 #ifdef  _CRAYT3D
00210         register short  shared;
00211         register long   ntot;   
00212         register long   numleft;        
00213         long            shrd[MAXSH];
00214 #endif
00215 
00216         if (cup->useq == 0)     /* If direct access file */
00217                 _ferr(css, FEBIONDA, "BUFFER IN");
00218 
00219         if (cup->ufmt)          /* If formatted file */
00220                 _ferr(css, FEBIONFM, "BUFFER IN");
00221 
00222         if (cup->uerr && !cup->unitchk)
00223                 _ferr(css, cup->uffsw.sw_error);
00224 
00225 /*
00226  *      This check taken out temporarily because we'd like to be able to
00227  *      follow an ENDFILE statement or a READ which encounters an endfile
00228  *      record with a BUFFER IN statement.  The sticky EOF principle should
00229  *      permit such a BUFFER IN to simply return an EOF status.  But what
00230  *      really happens is the preceding ENDFILE or READ statement sets 
00231  *      cup->uend, triggering an error here.  We really need a flag to
00232  *      store the status of the previous BUFFER IN/OUT statement which is
00233  *      separate from cup->uend.
00234  *
00235  *      if (cup->uend && !cup->unitchk)
00236  *              _ferr(css, FERDPEOF);
00237  */
00238 
00239         cup->unitchk    = 0;
00240         cup->uerr       = 0;
00241         elsize          = tip->elsize;  /* Data size in bytes */
00242         type90          = tip->type90;
00243 
00244 /*
00245  *      Adjust the word count depending on the type.
00246  */
00247         bytshft = ((sizeof(elsize) << 3) - 1) - _leadz(elsize); /* log2(elsize) */
00248 
00249         if (type90 == DVTYPE_ASCII) {   /* If character item */
00250                 uda     = _fcdtocp(bloc.fcd);
00251                 udax    = _fcdtocp(eloc.fcd);
00252                 itemlen = _fcdlen (eloc.fcd);
00253         }
00254         else {
00255 #ifdef  _CRAYT3D
00256                 shared  = 0;
00257 
00258                 if (_issddptr(bloc.v)) {
00259                         int     *tmpptr;
00260 
00261                         /* Shared data */
00262 
00263                         if (!_issddptr(eloc.v)) {
00264                                 _ferr(css, FEINTUNK);
00265                         }
00266 
00267                         shared  = 1;
00268                         ntot    = 0;
00269 
00270                         if ((cup->ufs == FS_FDC) && 
00271                                 (cup->uflagword & FFC_ASYNC)) {
00272                                 /* When we can do I/O from shared memory */
00273                                 /* we can support this. */
00274                                 _ferr(css, FESHRSUP);
00275                         }
00276 /*
00277  * When compiler spr 76429 (on T3D) is closed, we can try replacing 
00278  * the lines that use tmpptr with this.
00279  *                      items   = _sdd_read_offset((void *)eloc.v) -
00280  *                              _sdd_read_offset((void *)bloc.v) + 1;
00281  */
00282                         uda     = bloc.v;       /* temporary */
00283                         udax    = eloc.v;
00284                         tmpptr  = (int *)((int)udax & 0x7fffffffffffffff);
00285                         items   = *(tmpptr + 1);
00286                         tmpptr  = (int *)((int)uda & 0x7fffffffffffffff);
00287                         items   = items - *(tmpptr + 1) + 1;
00288                 }
00289                 else
00290 #endif  /* _CRAYT3D */
00291                 {
00292                         uda     = bloc.v;
00293                         udax    = eloc.v;
00294                 }
00295 
00296                 itemlen = elsize;
00297         }
00298 
00299 #ifdef  _CRAYT3D
00300         if (shared) {
00301                 bytes   = items << bytshft;
00302         }
00303         else 
00304 #endif
00305         {
00306                 bytes   = (udax - uda) + itemlen;
00307                 items   = bytes >> bytshft;
00308         }
00309 
00310         if (bytes < 0)
00311                 _ferr(css, FEBIOFWA, "BUFFER IN");
00312 
00313         mode            = (*recmode < 0) ? PARTIAL : FULL;
00314         cup->urecmode   = mode;
00315         cup->uwrt       = 0;
00316         state           = CNT;
00317 
00318         if ((items << bytshft) != bytes)
00319                 _ferr(css, FEBIOFWD);
00320 
00321 #ifdef  _CRAYT3D
00322         if ( !shared && cup->uasync ) {
00323 #else
00324         if (cup->uasync) {
00325 #endif
00326                 int     ubc = 0;
00327 
00328                 WAITIO(cup, _ferr(css, cup->uffsw.sw_error));
00329 
00330 #if     defined(_UNICOS) || defined(NUMERIC_DATA_CONVERSION_ENABLED)
00331 /*
00332  *              Pad word-aligned numeric data on word boundaries within
00333  *              the record for CRI and some foreign data formats. 
00334  */
00335                 if ((cup->urecpos & cup->ualignmask) != 0 &&
00336                     type90 != DVTYPE_ASCII && 
00337                     elsize > 4 ) {
00338                         int             padubc;
00339                         register int    pbytes;
00340                         int             padval;
00341 
00342                         COMPADD(cup, pbytes, padubc, padval);
00343 
00344                         if (pbytes != 0) {
00345                                 stat    = XRCALL(cup->ufp.fdc, readrtn)
00346                                                 cup->ufp.fdc,
00347                                                 WPTR2BP(&padval),
00348                                                 pbytes,
00349                                                 &cup->uffsw,
00350                                                 PARTIAL,
00351                                                 &padubc);
00352                                 if (stat != pbytes ||
00353                                     FFSTAT(cup->uffsw) != FFCNT) {
00354                                         cup->uerr       = 1;
00355                                         goto badpart;
00356                                 }
00357                                 cup->urecpos    += (stat << 3) - padubc;
00358                         }
00359                 }
00360 #endif  /* _UNICOS || NUMERIC_DATA_CONVERSION_ENABLED */
00361 
00362                 CLRSTAT(cup->uffsw);            /* clear status word */
00363                 FFSTAT(cup->uffsw)      = 0;    /* flag no status */
00364 
00365                 stat    = XRCALL(cup->ufp.fdc, readartn) cup->ufp.fdc,
00366                                         CPTR2BP(uda),
00367                                         bytes,
00368                                         &cup->uffsw,
00369                                         mode,
00370                                         &ubc);
00371 
00372                 cup->uasync     = ASYNC_ACTIVE; /* flag last op was async */
00373 
00374                 if (stat < 0)
00375                         cup->uerr       = 1;
00376         }
00377         else {
00378 #ifdef  _CRAYT3D
00379                 register long   chunk;
00380 
00381                 if (shared) {
00382                         chunk   = (MAXSH / elsize) * sizeof(long);
00383                         uda     = (char *)shrd;
00384                         numleft = items;
00385                 }
00386                 do {
00387                         if (shared) {
00388                                 items   = MIN(chunk, numleft);
00389                                 numleft = numleft - items;
00390 
00391                                 if (numleft == 0)
00392                                         mode    = cup->urecmode;
00393                                 else
00394                                         mode    = PARTIAL;
00395                         }
00396 #endif
00397 
00398                         tip->count      = items;
00399                 
00400                         stat    = _frwd(cup, uda, tip, mode, (int *) NULL,
00401                                         (long *) NULL, &state);
00402 
00403 #ifdef  _CRAYT3D
00404                         if (stat > 0)
00405                                 if (shared) {
00406                                         _cpytosdd(bloc.v, (long *)uda, stat,
00407                                                 elsize / sizeof(long), 1, ntot);        
00408                                         ntot    = ntot + stat;
00409                                 }
00410 
00411                 } while (shared && (stat == items) && (numleft > 0));
00412 #endif
00413 
00414                 cup->ulrecl     = 0;
00415 
00416                 if ( stat == IOERR ) {
00417                         cup->uerr               = 1;
00418                         cup->uffsw.sw_error     = errno;
00419                 }
00420                 else if (state == EOF) 
00421                         cup->uend       = PHYSICAL_ENDFILE;
00422                 else if (state == EOD) {
00423                         if (cup->uend == 0)
00424                                 cup->uend       = LOGICAL_ENDFILE;
00425                 }
00426                 else {
00427                         /*
00428                          * Set ulrecl to returned item count -> bits
00429                          */
00430 #ifdef  _CRAYT3D
00431                         if (shared)
00432                                 cup->ulrecl     = ntot << (bytshft + 3);
00433                         else
00434 #endif
00435                                 cup->ulrecl     = stat << (bytshft + 3);
00436 
00437                         cup->uend       = BEFORE_ENDFILE;
00438                 }
00439 
00440         }
00441 
00442 /*
00443  *      If mode is FULL or status is BOD, EOR, EOF, EOD, ERR then
00444  *      clear ulastyp to avoid padd on next operation.
00445  */
00446         cup->ulastyp    = type90;
00447 
00448         if (cup->urecmode == FULL || state != CNT) {
00449 badpart:
00450                 cup->ulastyp    = DVTYPE_TYPELESS;
00451                 cup->urecpos    = 0;
00452         }
00453 
00454 #ifdef  _CRAYT3D
00455         if (shared)
00456                 _remote_write_barrier();
00457 #endif
00458 
00459         STMT_END(cup, T_BUFIN, NULL, css);
00460 
00461         return;
00462 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines