-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/romio/adio/ad_nfs/ad_nfs_read.c
        -:    0:Graph:ad_nfs_read.gcno
        -:    0:Data:ad_nfs_read.gcda
        -:    0:Runs:224
        -:    0:Programs:67
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/* 
        -:    3: *
        -:    4: *   Copyright (C) 1997 University of Chicago. 
        -:    5: *   See COPYRIGHT notice in top-level directory.
        -:    6: */
        -:    7:
        -:    8:#include "ad_nfs.h"
        -:    9:#include "adio_extern.h"
        -:   10:
        -:   11:void ADIOI_NFS_ReadContig(ADIO_File fd, void *buf, int count, 
        -:   12:                     MPI_Datatype datatype, int file_ptr_type,
        -:   13:		     ADIO_Offset offset, ADIO_Status *status, int *error_code)
    #####:   14:{
    #####:   15:    int err=-1, datatype_size, len;
        -:   16:    static char myname[] = "ADIOI_NFS_READCONTIG";
        -:   17:
    #####:   18:    MPI_Type_size(datatype, &datatype_size);
    #####:   19:    len = datatype_size * count;
        -:   20:
    #####:   21:    if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {
    #####:   22:	if (fd->fp_sys_posn != offset) {
        -:   23:#ifdef ADIOI_MPE_LOGGING
        -:   24:            MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
        -:   25:#endif
    #####:   26:	    lseek(fd->fd_sys, offset, SEEK_SET);
        -:   27:#ifdef ADIOI_MPE_LOGGING
        -:   28:            MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
        -:   29:#endif
        -:   30:        }
    #####:   31:	if (fd->atomicity)
    #####:   32:	    ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
    #####:   33:	else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
        -:   34:#ifdef ADIOI_MPE_LOGGING
        -:   35:        MPE_Log_event( ADIOI_MPE_read_a, 0, NULL );
        -:   36:#endif
    #####:   37:	err = read(fd->fd_sys, buf, len);
        -:   38:#ifdef ADIOI_MPE_LOGGING
        -:   39:        MPE_Log_event( ADIOI_MPE_read_b, 0, NULL );
        -:   40:#endif
    #####:   41:	ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
    #####:   42:	fd->fp_sys_posn = offset + err;
        -:   43:	/* individual file pointer not updated */        
        -:   44:    }
        -:   45:    else {  /* read from curr. location of ind. file pointer */
    #####:   46:	offset = fd->fp_ind;
    #####:   47:	if (fd->fp_sys_posn != fd->fp_ind) {
        -:   48:#ifdef ADIOI_MPE_LOGGING
        -:   49:            MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
        -:   50:#endif
    #####:   51:	    lseek(fd->fd_sys, fd->fp_ind, SEEK_SET);
        -:   52:#ifdef ADIOI_MPE_LOGGING
        -:   53:            MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
        -:   54:#endif
        -:   55:        }
    #####:   56:	if (fd->atomicity)
    #####:   57:	    ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
    #####:   58:	else ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);
        -:   59:#ifdef ADIOI_MPE_LOGGING
        -:   60:        MPE_Log_event( ADIOI_MPE_read_a, 0, NULL );
        -:   61:#endif
    #####:   62:	err = read(fd->fd_sys, buf, len);
        -:   63:#ifdef ADIOI_MPE_LOGGING
        -:   64:        MPE_Log_event( ADIOI_MPE_read_b, 0, NULL );
        -:   65:#endif
    #####:   66:	ADIOI_UNLOCK(fd, offset, SEEK_SET, len);
    #####:   67:	fd->fp_ind += err;
    #####:   68:	fd->fp_sys_posn = fd->fp_ind;
        -:   69:    }
        -:   70:
        -:   71:    /* --BEGIN ERROR HANDLING-- */
    #####:   72:    if (err == -1) {
    #####:   73:	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
        -:   74:					   myname, __LINE__, MPI_ERR_IO,
        -:   75:					   "**io", "**io %s", strerror(errno));
    #####:   76:	return;
        -:   77:    }
        -:   78:    /* --END ERROR HANDLING-- */
        -:   79:
        -:   80:#ifdef HAVE_STATUS_SET_BYTES
    #####:   81:    MPIR_Status_set_bytes(status, datatype, err);
        -:   82:#endif
        -:   83:
    #####:   84:    *error_code = MPI_SUCCESS;
        -:   85:}
        -:   86:
        -:   87:
        -:   88:
        -:   89:#ifdef ADIOI_MPE_LOGGING
        -:   90:#define ADIOI_BUFFERED_READ \
        -:   91:{ \
        -:   92:    if (req_off >= readbuf_off + readbuf_len) { \
        -:   93:	readbuf_off = req_off; \
        -:   94:	readbuf_len = (int) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));\
        -:   95:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
        -:   96:	lseek(fd->fd_sys, readbuf_off, SEEK_SET);\
        -:   97:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
        -:   98:        if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off, SEEK_SET, readbuf_len);\
        -:   99:        MPE_Log_event( ADIOI_MPE_read_a, 0, NULL ); \
        -:  100:        err = read(fd->fd_sys, readbuf, readbuf_len);\
        -:  101:        MPE_Log_event( ADIOI_MPE_read_b, 0, NULL ); \
        -:  102:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off, SEEK_SET, readbuf_len);\
        -:  103:        if (err == -1) err_flag = 1; \
        -:  104:    } \
        -:  105:    while (req_len > readbuf_off + readbuf_len - req_off) { \
        -:  106:	partial_read = (int) (readbuf_off + readbuf_len - req_off); \
        -:  107:	tmp_buf = (char *) ADIOI_Malloc(partial_read); \
        -:  108:	memcpy(tmp_buf, readbuf+readbuf_len-partial_read, partial_read); \
        -:  109:	ADIOI_Free(readbuf); \
        -:  110:	readbuf = (char *) ADIOI_Malloc(partial_read + max_bufsize); \
        -:  111:	memcpy(readbuf, tmp_buf, partial_read); \
        -:  112:	ADIOI_Free(tmp_buf); \
        -:  113:	readbuf_off += readbuf_len-partial_read; \
        -:  114:	readbuf_len = (int) (partial_read + ADIOI_MIN(max_bufsize, \
        -:  115:				       end_offset-readbuf_off+1)); \
        -:  116:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL ); \
        -:  117:	lseek(fd->fd_sys, readbuf_off+partial_read, SEEK_SET);\
        -:  118:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL ); \
        -:  119:        if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off+partial_read, SEEK_SET, readbuf_len-partial_read);\
        -:  120:        MPE_Log_event( ADIOI_MPE_read_a, 0, NULL ); \
        -:  121:        err = read(fd->fd_sys, readbuf+partial_read, readbuf_len-partial_read);\
        -:  122:        MPE_Log_event( ADIOI_MPE_read_b, 0, NULL ); \
        -:  123:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off+partial_read, SEEK_SET, readbuf_len-partial_read);\
        -:  124:        if (err == -1) err_flag = 1; \
        -:  125:    } \
        -:  126:    memcpy((char *)buf + userbuf_off, readbuf+req_off-readbuf_off, req_len); \
        -:  127:}
        -:  128:#else
        -:  129:#define ADIOI_BUFFERED_READ \
        -:  130:{ \
        -:  131:    if (req_off >= readbuf_off + readbuf_len) { \
        -:  132:	readbuf_off = req_off; \
        -:  133:	readbuf_len = (int) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));\
        -:  134:	lseek(fd->fd_sys, readbuf_off, SEEK_SET);\
        -:  135:        if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off, SEEK_SET, readbuf_len);\
        -:  136:        err = read(fd->fd_sys, readbuf, readbuf_len);\
        -:  137:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off, SEEK_SET, readbuf_len);\
        -:  138:        if (err == -1) err_flag = 1; \
        -:  139:    } \
        -:  140:    while (req_len > readbuf_off + readbuf_len - req_off) { \
        -:  141:	partial_read = (int) (readbuf_off + readbuf_len - req_off); \
        -:  142:	tmp_buf = (char *) ADIOI_Malloc(partial_read); \
        -:  143:	memcpy(tmp_buf, readbuf+readbuf_len-partial_read, partial_read); \
        -:  144:	ADIOI_Free(readbuf); \
        -:  145:	readbuf = (char *) ADIOI_Malloc(partial_read + max_bufsize); \
        -:  146:	memcpy(readbuf, tmp_buf, partial_read); \
        -:  147:	ADIOI_Free(tmp_buf); \
        -:  148:	readbuf_off += readbuf_len-partial_read; \
        -:  149:	readbuf_len = (int) (partial_read + ADIOI_MIN(max_bufsize, \
        -:  150:				       end_offset-readbuf_off+1)); \
        -:  151:	lseek(fd->fd_sys, readbuf_off+partial_read, SEEK_SET);\
        -:  152:        if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off+partial_read, SEEK_SET, readbuf_len-partial_read);\
        -:  153:        err = read(fd->fd_sys, readbuf+partial_read, readbuf_len-partial_read);\
        -:  154:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off+partial_read, SEEK_SET, readbuf_len-partial_read);\
        -:  155:        if (err == -1) err_flag = 1; \
        -:  156:    } \
        -:  157:    memcpy((char *)buf + userbuf_off, readbuf+req_off-readbuf_off, req_len); \
        -:  158:}
        -:  159:#endif
        -:  160:
        -:  161:
        -:  162:void ADIOI_NFS_ReadStrided(ADIO_File fd, void *buf, int count,
        -:  163:                       MPI_Datatype datatype, int file_ptr_type,
        -:  164:                       ADIO_Offset offset, ADIO_Status *status, int
        -:  165:                       *error_code)
    #####:  166:{
        -:  167:/* offset is in units of etype relative to the filetype. */
        -:  168:
        -:  169:    ADIOI_Flatlist_node *flat_buf, *flat_file;
    #####:  170:    int i, j, k, err=-1, brd_size, frd_size=0, st_index=0;
        -:  171:    int bufsize, num, size, sum, n_etypes_in_filetype, size_in_filetype;
        -:  172:    int n_filetypes, etype_in_filetype;
    #####:  173:    ADIO_Offset abs_off_in_filetype=0;
        -:  174:    int filetype_size, etype_size, buftype_size, req_len, partial_read;
        -:  175:    MPI_Aint filetype_extent, buftype_extent; 
        -:  176:    int buf_count, buftype_is_contig, filetype_is_contig;
        -:  177:    ADIO_Offset userbuf_off;
    #####:  178:    ADIO_Offset off, req_off, disp, end_offset=0, readbuf_off, start_off;
        -:  179:    char *readbuf, *tmp_buf, *value;
        -:  180:    int flag, st_frd_size, st_n_filetypes, readbuf_len;
    #####:  181:    int new_brd_size, new_frd_size, err_flag=0, info_flag, max_bufsize;
        -:  182:
        -:  183:    static char myname[] = "ADIOI_NFS_READSTRIDED";
        -:  184:
    #####:  185:    ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);
    #####:  186:    ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
        -:  187:
    #####:  188:    MPI_Type_size(fd->filetype, &filetype_size);
    #####:  189:    if ( ! filetype_size ) {
    #####:  190:	*error_code = MPI_SUCCESS; 
    #####:  191:	return;
        -:  192:    }
        -:  193:
    #####:  194:    MPI_Type_extent(fd->filetype, &filetype_extent);
    #####:  195:    MPI_Type_size(datatype, &buftype_size);
    #####:  196:    MPI_Type_extent(datatype, &buftype_extent);
    #####:  197:    etype_size = fd->etype_size;
        -:  198:
    #####:  199:    bufsize = buftype_size * count;
        -:  200:
        -:  201:/* get max_bufsize from the info object. */
        -:  202:
    #####:  203:    value = (char *) ADIOI_Malloc((MPI_MAX_INFO_VAL+1)*sizeof(char));
    #####:  204:    MPI_Info_get(fd->info, "ind_rd_buffer_size", MPI_MAX_INFO_VAL, value, 
        -:  205:                 &info_flag);
    #####:  206:    max_bufsize = atoi(value);
    #####:  207:    ADIOI_Free(value);
        -:  208:
    #####:  209:    if (!buftype_is_contig && filetype_is_contig) {
        -:  210:
        -:  211:/* noncontiguous in memory, contiguous in file. */
        -:  212:
    #####:  213:	ADIOI_Flatten_datatype(datatype);
    #####:  214:	flat_buf = ADIOI_Flatlist;
    #####:  215:	while (flat_buf->type != datatype) flat_buf = flat_buf->next;
        -:  216:
    #####:  217:        off = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind : 
        -:  218:                 fd->disp + etype_size * offset;
        -:  219:
    #####:  220:	start_off = off;
    #####:  221:	end_offset = off + bufsize - 1;
    #####:  222:        readbuf_off = off;
    #####:  223:        readbuf = (char *) ADIOI_Malloc(max_bufsize);
    #####:  224:        readbuf_len = (int) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));
        -:  225:
        -:  226:/* if atomicity is true, lock (exclusive) the region to be accessed */
    #####:  227:        if (fd->atomicity)
    #####:  228:            ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
        -:  229:
        -:  230:#ifdef ADIOI_MPE_LOGGING
        -:  231:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
        -:  232:#endif
    #####:  233:	lseek(fd->fd_sys, readbuf_off, SEEK_SET);
        -:  234:#ifdef ADIOI_MPE_LOGGING
        -:  235:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
        -:  236:#endif
    #####:  237:        if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, readbuf_off, SEEK_SET, readbuf_len);
        -:  238:#ifdef ADIOI_MPE_LOGGING
        -:  239:        MPE_Log_event( ADIOI_MPE_read_a, 0, NULL );
        -:  240:#endif
    #####:  241:        err = read(fd->fd_sys, readbuf, readbuf_len);
        -:  242:#ifdef ADIOI_MPE_LOGGING
        -:  243:        MPE_Log_event( ADIOI_MPE_read_b, 0, NULL );
        -:  244:#endif
    #####:  245:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, readbuf_off, SEEK_SET, readbuf_len);
    #####:  246:        if (err == -1) err_flag = 1;
        -:  247:
    #####:  248:        for (j=0; j<count; j++) 
    #####:  249:            for (i=0; i<flat_buf->count; i++) {
    #####:  250:                userbuf_off = j*buftype_extent + flat_buf->indices[i];
    #####:  251:		req_off = off;
    #####:  252:		req_len = flat_buf->blocklens[i];
    #####:  253:		ADIOI_BUFFERED_READ
    #####:  254:                off += flat_buf->blocklens[i];
        -:  255:            }
        -:  256:
    #####:  257:        if (fd->atomicity)
    #####:  258:            ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
        -:  259:
    #####:  260:        if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
        -:  261:
    #####:  262:	ADIOI_Free(readbuf); /* malloced in the buffered_read macro */
        -:  263:
    #####:  264:	if (err_flag) {
    #####:  265:	    *error_code = MPIO_Err_create_code(MPI_SUCCESS,
        -:  266:					       MPIR_ERR_RECOVERABLE, myname,
        -:  267:					       __LINE__, MPI_ERR_IO, "**io",
        -:  268:					       "**io %s", strerror(errno));
        -:  269:	}
    #####:  270:	else *error_code = MPI_SUCCESS;
        -:  271:    }
        -:  272:
        -:  273:    else {  /* noncontiguous in file */
        -:  274:
        -:  275:/* filetype already flattened in ADIO_Open */
    #####:  276:	flat_file = ADIOI_Flatlist;
    #####:  277:	while (flat_file->type != fd->filetype) flat_file = flat_file->next;
    #####:  278:	disp = fd->disp;
        -:  279:
    #####:  280:	if (file_ptr_type == ADIO_INDIVIDUAL) {
        -:  281:          /* Wei-keng reworked type processing to be a bit more efficient */
    #####:  282:           offset       = fd->fp_ind - disp;
    #####:  283:           n_filetypes  = (offset - flat_file->indices[0]) / filetype_extent;
    #####:  284:          offset -= (ADIO_Offset)n_filetypes * filetype_extent;
        -:  285:          /* now offset is local to this extent */
        -:  286: 
        -:  287:           /* find the block where offset is located, skip blocklens[i]==0 */
    #####:  288:           for (i=0; i<flat_file->count; i++) {
        -:  289:               ADIO_Offset dist;
    #####:  290:               if (flat_file->blocklens[i] == 0) continue;
    #####:  291:               dist = flat_file->indices[i] + flat_file->blocklens[i] - offset;
        -:  292:               /* frd_size is from offset to the end of block i */
    #####:  293:              if (dist == 0) {
    #####:  294:                  i++;
    #####:  295:                  offset   = flat_file->indices[i];
    #####:  296:                  frd_size = flat_file->blocklens[i];
    #####:  297:                  break;
        -:  298:              }
    #####:  299:              if (dist > 0 ) { 
    #####:  300:                   frd_size = dist;
    #####:  301:		   break;
        -:  302:              }
        -:  303:          }
    #####:  304:           st_index = i;  /* starting index in flat_file->indices[] */
    #####:  305:           offset += disp + (ADIO_Offset)n_filetypes*filetype_extent;
        -:  306:       }
        -:  307:	else {
    #####:  308:	    n_etypes_in_filetype = filetype_size/etype_size;
    #####:  309:	    n_filetypes = (int) (offset / n_etypes_in_filetype);
    #####:  310:	    etype_in_filetype = (int) (offset % n_etypes_in_filetype);
    #####:  311:	    size_in_filetype = etype_in_filetype * etype_size;
        -:  312: 
    #####:  313:	    sum = 0;
    #####:  314:	    for (i=0; i<flat_file->count; i++) {
    #####:  315:		sum += flat_file->blocklens[i];
    #####:  316:		if (sum > size_in_filetype) {
    #####:  317:		    st_index = i;
    #####:  318:		    frd_size = sum - size_in_filetype;
    #####:  319:		    abs_off_in_filetype = flat_file->indices[i] +
        -:  320:			size_in_filetype - (sum - flat_file->blocklens[i]);
    #####:  321:		    break;
        -:  322:		}
        -:  323:	    }
        -:  324:
        -:  325:	    /* abs. offset in bytes in the file */
    #####:  326:	    offset = disp + (ADIO_Offset) n_filetypes*filetype_extent + 
        -:  327:		    abs_off_in_filetype;
        -:  328:	}
        -:  329:
    #####:  330:        start_off = offset;
        -:  331:
        -:  332:       /* Wei-keng Liao: read request is within a single flat_file contig
        -:  333:        * block e.g. with subarray types that actually describe the whole
        -:  334:        * array */
    #####:  335:       if (buftype_is_contig && bufsize <= frd_size) {
    #####:  336:            ADIO_ReadContig(fd, buf, bufsize, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
        -:  337:                             offset, status, error_code);
        -:  338:
    #####:  339:           if (file_ptr_type == ADIO_INDIVIDUAL) {
        -:  340:                /* update MPI-IO file pointer to point to the first byte that 
        -:  341:                * can be accessed in the fileview. */
    #####:  342:               fd->fp_ind = offset + bufsize;
    #####:  343:               if (bufsize == frd_size) {
        -:  344:                   do {
    #####:  345:                       st_index++;
    #####:  346:                       if (st_index == flat_file->count) {
    #####:  347:                           st_index = 0;
    #####:  348:                           n_filetypes++;
        -:  349:                       }
    #####:  350:                    } while (flat_file->blocklens[st_index] == 0);
    #####:  351:                   fd->fp_ind = disp + flat_file->indices[st_index]
        -:  352:                               + n_filetypes*filetype_extent;
        -:  353:               }
        -:  354:           }
    #####:  355:           fd->fp_sys_posn = -1;   /* set it to null. */ 
        -:  356:#ifdef HAVE_STATUS_SET_BYTES
    #####:  357:           MPIR_Status_set_bytes(status, datatype, bufsize);
        -:  358:#endif 
    #####:  359:            return;
        -:  360:       }
        -:  361:
        -:  362:       /* Calculate end_offset, the last byte-offset that will be accessed.
        -:  363:         e.g., if start_offset=0 and 100 bytes to be read, end_offset=99*/
        -:  364:
    #####:  365:	st_frd_size = frd_size;
    #####:  366:	st_n_filetypes = n_filetypes;
    #####:  367:	i = 0;
    #####:  368:	j = st_index;
    #####:  369:	off = offset;
    #####:  370:	frd_size = ADIOI_MIN(st_frd_size, bufsize);
    #####:  371:	while (i < bufsize) {
    #####:  372:	    i += frd_size;
    #####:  373:	    end_offset = off + frd_size - 1;
    #####:  374:            j = (j+1) % flat_file->count;
    #####:  375:            n_filetypes += (j == 0) ? 1 : 0;
    #####:  376:            while (flat_file->blocklens[j]==0) {
    #####:  377:               j = (j+1) % flat_file->count;
    #####:  378:               n_filetypes += (j == 0) ? 1 : 0;
        -:  379:	    }
        -:  380:
    #####:  381:	    off = disp + flat_file->indices[j] + (ADIO_Offset) n_filetypes*filetype_extent;
    #####:  382:	    frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
        -:  383:	}
        -:  384:
        -:  385:/* if atomicity is true, lock (exclusive) the region to be accessed */
    #####:  386:        if (fd->atomicity)
    #####:  387:            ADIOI_WRITE_LOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
        -:  388:
        -:  389:        /* initial read into readbuf */
    #####:  390:	readbuf_off = offset;
    #####:  391:	readbuf = (char *) ADIOI_Malloc(max_bufsize);
    #####:  392:	readbuf_len = (int) (ADIOI_MIN(max_bufsize, end_offset-readbuf_off+1));
        -:  393:
        -:  394:#ifdef ADIOI_MPE_LOGGING
        -:  395:        MPE_Log_event( ADIOI_MPE_lseek_a, 0, NULL );
        -:  396:#endif
    #####:  397:	lseek(fd->fd_sys, offset, SEEK_SET);
        -:  398:#ifdef ADIOI_MPE_LOGGING
        -:  399:        MPE_Log_event( ADIOI_MPE_lseek_b, 0, NULL );
        -:  400:#endif
    #####:  401:        if (!(fd->atomicity)) ADIOI_READ_LOCK(fd, offset, SEEK_SET, readbuf_len);
        -:  402:#ifdef ADIOI_MPE_LOGGING
        -:  403:        MPE_Log_event( ADIOI_MPE_read_a, 0, NULL );
        -:  404:#endif
    #####:  405:        err = read(fd->fd_sys, readbuf, readbuf_len);
        -:  406:#ifdef ADIOI_MPE_LOGGING
        -:  407:        MPE_Log_event( ADIOI_MPE_read_b, 0, NULL );
        -:  408:#endif
    #####:  409:        if (!(fd->atomicity)) ADIOI_UNLOCK(fd, offset, SEEK_SET, readbuf_len);
        -:  410:
    #####:  411:        if (err == -1) err_flag = 1;
        -:  412:
    #####:  413:	if (buftype_is_contig && !filetype_is_contig) {
        -:  414:
        -:  415:/* contiguous in memory, noncontiguous in file. should be the most
        -:  416:   common case. */
        -:  417:
    #####:  418:	    i = 0;
    #####:  419:	    j = st_index;
    #####:  420:	    off = offset;
    #####:  421:	    n_filetypes = st_n_filetypes;
    #####:  422:	    frd_size = ADIOI_MIN(st_frd_size, bufsize);
    #####:  423:	    while (i < bufsize) {
    #####:  424:                if (frd_size) { 
        -:  425:                    /* TYPE_UB and TYPE_LB can result in 
        -:  426:                       frd_size = 0. save system call in such cases */ 
        -:  427:		    /* lseek(fd->fd_sys, off, SEEK_SET);
        -:  428:		    err = read(fd->fd_sys, ((char *) buf) + i, frd_size);*/
        -:  429:
    #####:  430:		    req_off = off;
    #####:  431:		    req_len = frd_size;
    #####:  432:		    userbuf_off = i;
    #####:  433:		    ADIOI_BUFFERED_READ
        -:  434:		}
    #####:  435:		i += frd_size;
        -:  436:
    #####:  437:                if (off + frd_size < disp + flat_file->indices[j] +
        -:  438:                   flat_file->blocklens[j] + (ADIO_Offset) n_filetypes*filetype_extent)
    #####:  439:                       off += frd_size;
        -:  440:                /* did not reach end of contiguous block in filetype.
        -:  441:                   no more I/O needed. off is incremented by frd_size. */
        -:  442:                else {
    #####:  443:                    j = (j+1) % flat_file->count;
    #####:  444:                    n_filetypes += (j == 0) ? 1 : 0;
    #####:  445:                    while (flat_file->blocklens[j]==0) {
    #####:  446:                        j = (j+1) % flat_file->count;
    #####:  447:                        n_filetypes += (j == 0) ? 1 : 0;
        -:  448:                    }
    #####:  449:		    off = disp + flat_file->indices[j] + 
        -:  450:                                        (ADIO_Offset) n_filetypes*filetype_extent;
    #####:  451:		    frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i);
        -:  452:		}
        -:  453:	    }
        -:  454:	}
        -:  455:	else {
        -:  456:/* noncontiguous in memory as well as in file */
        -:  457:
    #####:  458:	    ADIOI_Flatten_datatype(datatype);
    #####:  459:	    flat_buf = ADIOI_Flatlist;
    #####:  460:	    while (flat_buf->type != datatype) flat_buf = flat_buf->next;
        -:  461:
    #####:  462:	    k = num = buf_count = 0;
    #####:  463:	    i = (int) (flat_buf->indices[0]);
    #####:  464:	    j = st_index;
    #####:  465:	    off = offset;
    #####:  466:	    n_filetypes = st_n_filetypes;
    #####:  467:	    frd_size = st_frd_size;
    #####:  468:	    brd_size = flat_buf->blocklens[0];
        -:  469:
    #####:  470:	    while (num < bufsize) {
    #####:  471:		size = ADIOI_MIN(frd_size, brd_size);
    #####:  472:		if (size) {
        -:  473:		    /* lseek(fd->fd_sys, off, SEEK_SET);
        -:  474:		    err = read(fd->fd_sys, ((char *) buf) + i, size); */
        -:  475:
    #####:  476:		    req_off = off;
    #####:  477:		    req_len = size;
    #####:  478:		    userbuf_off = i;
    #####:  479:		    ADIOI_BUFFERED_READ
        -:  480:		}
        -:  481:
    #####:  482:		new_frd_size = frd_size;
    #####:  483:		new_brd_size = brd_size;
        -:  484:
    #####:  485:		if (size == frd_size) {
        -:  486:/* reached end of contiguous block in file */
    #####:  487:                    j = (j+1) % flat_file->count;
    #####:  488:                    n_filetypes += (j == 0) ? 1 : 0;
    #####:  489:                    while (flat_file->blocklens[j]==0) {
    #####:  490:                        j = (j+1) % flat_file->count;
    #####:  491:                        n_filetypes += (j == 0) ? 1 : 0;
        -:  492:                    }
    #####:  493:		    off = disp + flat_file->indices[j] + 
        -:  494:                                              (ADIO_Offset) n_filetypes*filetype_extent;
        -:  495:
    #####:  496:		    new_frd_size = flat_file->blocklens[j];
    #####:  497:		    if (size != brd_size) {
    #####:  498:			i += size;
    #####:  499:			new_brd_size -= size;
        -:  500:		    }
        -:  501:		}
        -:  502:
    #####:  503:		if (size == brd_size) {
        -:  504:/* reached end of contiguous block in memory */
        -:  505:
    #####:  506:		    k = (k + 1)%flat_buf->count;
    #####:  507:		    buf_count++;
    #####:  508:		    i = (int) (buftype_extent*(buf_count/flat_buf->count) +
        -:  509:			flat_buf->indices[k]); 
    #####:  510:		    new_brd_size = flat_buf->blocklens[k];
    #####:  511:		    if (size != frd_size) {
    #####:  512:			off += size;
    #####:  513:			new_frd_size -= size;
        -:  514:		    }
        -:  515:		}
    #####:  516:		num += size;
    #####:  517:		frd_size = new_frd_size;
    #####:  518:                brd_size = new_brd_size;
        -:  519:	    }
        -:  520:	}
        -:  521:	
    #####:  522:        if (fd->atomicity)
    #####:  523:            ADIOI_UNLOCK(fd, start_off, SEEK_SET, end_offset-start_off+1);
        -:  524:
    #####:  525:	if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off;
        -:  526:
    #####:  527:	ADIOI_Free(readbuf); /* malloced in the buffered_read macro */
        -:  528:
    #####:  529:	if (err_flag) {
    #####:  530:	    *error_code = MPIO_Err_create_code(MPI_SUCCESS,
        -:  531:					       MPIR_ERR_RECOVERABLE, myname,
        -:  532:					       __LINE__, MPI_ERR_IO, "**io",
        -:  533:					       "**io %s", strerror(errno));
        -:  534:	}
    #####:  535:	else *error_code = MPI_SUCCESS;
        -:  536:    }
        -:  537:
    #####:  538:    fd->fp_sys_posn = -1;   /* set it to null. */
        -:  539:
        -:  540:#ifdef HAVE_STATUS_SET_BYTES
    #####:  541:    MPIR_Status_set_bytes(status, datatype, bufsize);
        -:  542:/* This is a temporary way of filling in status. The right way is to 
        -:  543:   keep track of how much data was actually read and placed in buf 
        -:  544:   by ADIOI_BUFFERED_READ. */
        -:  545:#endif
        -:  546:
    #####:  547:    if (!buftype_is_contig) ADIOI_Delete_flattened(datatype);
        -:  548:}