Example #1
0
File: dio.c Project: 151706061/ITK
size_t
airDioWrite(int fd, const void *_ptr, size_t size) {
  size_t rit, totalrit;
  int align, min, max, flags;
  size_t remain, part;
  char *ptr;

  if (!( _ptr && (airNoDio_okay == airDioTest(fd, _ptr, size)) )) {
    return 0;
  }

  flags = fcntl(fd, F_GETFL);
  fcntl(fd, F_SETFL, flags | FDIRECT);
  airDioInfo(&align, &min, &max, fd);
  remain = size;
  totalrit = 0;
  ptr = (char*)_ptr;
  do {
    part = AIR_MIN(remain, max);
    rit = write(fd, ptr, part);
    totalrit += rit;
    if (rit != part) {
      break;
    }
    ptr += rit;
    remain -= rit;
  } while (remain);
  fcntl(fd, F_SETFL, flags);

  return totalrit;
}
Example #2
0
File: dio.c Project: 151706061/ITK
size_t
airDioRead(int fd, void *_ptr, size_t size) {
  size_t red, totalred;
  int align, min, max, flags;
  size_t remain, part;
  char *ptr;

  if (!( _ptr && airNoDio_okay == airDioTest(fd, _ptr, size) )) {
    return 0;
  }

  flags = fcntl(fd, F_GETFL);
  fcntl(fd, F_SETFL, flags | FDIRECT);
  airDioInfo(&align, &min, &max, fd);
  remain = size;
  totalred = 0;
  ptr = (char*)_ptr;
  do {
    part = AIR_MIN(remain, max);
    red = read(fd, ptr, part);
    totalred += red;
    if (red != part) {
      break;
    }
    ptr += red;
    remain -= red;
  } while (remain);
  fcntl(fd, F_SETFL, flags);

  return totalred;
}
static int
_nrrdEncodingRaw_read(FILE *file, void *data, size_t elementNum,
                      Nrrd *nrrd, NrrdIoState *nio) {
  static const char me[]="_nrrdEncodingRaw_read";
  size_t ret, bsize;
  int fd, dio, car;
  long savePos;
  char *data_c;
  size_t elementSize, maxChunkSize, remainderValue, chunkSize;
  size_t retTmp;
  char stmp[3][AIR_STRLEN_SMALL];

  bsize = nrrdElementSize(nrrd)*elementNum;
  if (nio->format->usesDIO) {
    fd = fileno(file);
    dio = airDioTest(fd, data, bsize);
  } else {
    fd = -1;
    dio = airNoDio_format;
  }
  if (airNoDio_okay == dio) {
    if (2 <= nrrdStateVerboseIO) {
      fprintf(stderr, "with direct I/O ... ");
    }
    ret = airDioRead(fd, data, bsize);
    if (ret != bsize) {
      biffAddf(NRRD, "%s: airDioRead got read only %s of %sbytes "
               "(%g%% of expected)", me,
               airSprintSize_t(stmp[0], ret),
               airSprintSize_t(stmp[1], bsize),
               100.0*AIR_CAST(double, ret)/AIR_CAST(double, bsize));
      return 1;
    }
  } else {
Example #4
0
int
_nrrdEncodingRaw_write(FILE *file, const void *data, size_t elementNum,
                       const Nrrd *nrrd, NrrdIoState *nio) {
  char me[]="_nrrdEncodingRaw_write", err[BIFF_STRLEN];
  int fd, dio;
  size_t ret, bsize;
  
  bsize = nrrdElementSize(nrrd)*elementNum;
  if (nio->format->usesDIO) {
    fd = fileno(file);
    dio = airDioTest(fd, data, bsize);
  } else {
    fd = -1;
    dio = airNoDio_format;
  }
  if (airNoDio_okay == dio) {
    if (2 <= nrrdStateVerboseIO) {
      fprintf(stderr, "with direct I/O ... ");
    }
    ret = airDioWrite(fd, data, bsize);
    if (ret != bsize) {
      sprintf(err, "%s: airDioWrite wrote only "
              _AIR_SIZE_T_CNV " of " _AIR_SIZE_T_CNV " bytes "
              "(%g%% of expected)", me,
              ret, bsize, 100.0*ret/bsize);
      biffAdd(NRRD, err); return 1;
    }
  } else {
    if (2 <= nrrdStateVerboseIO) {
      if (AIR_DIO && nio->format->usesDIO) {
        fprintf(stderr, "with fread(), not DIO: %s ...", airNoDioErr(dio));
      }
    }
    ret = fwrite(data, nrrdElementSize(nrrd), elementNum, file);
    if (ret != elementNum) {
      sprintf(err, "%s: fwrite wrote read only "
              _AIR_SIZE_T_CNV " " _AIR_SIZE_T_CNV "-sized things, not " 
              _AIR_SIZE_T_CNV " (%g%% of expected)", me,
              ret, nrrdElementSize(nrrd), elementNum,
              100.0*ret/elementNum);
      biffAdd(NRRD, err); return 1;
    }
    fflush(file);
    /*
    if (ferror(file)) {
      sprintf(err, "%s: ferror returned non-zero", me);
      biffAdd(NRRD, err); return 1;
    }
    */
  }
  return 0;
}
Example #5
0
int
_nrrdEncodingRaw_read(FILE *file, void *data, size_t elementNum,
                      Nrrd *nrrd, NrrdIoState *nio) {
  static const char me[]="_nrrdEncodingRaw_read";
  size_t ret, bsize;
  int fd, dio, car;
  long savePos;
  char *data_c;
  size_t elementSize, maxChunkSize, remainder, chunkSize;
  size_t retTmp;

  bsize = nrrdElementSize(nrrd)*elementNum;
  if (nio->format->usesDIO) {
    fd = fileno(file);
    dio = airDioTest(fd, data, bsize);
  } else {
    fd = -1;
    dio = airNoDio_format;
  }
  if (airNoDio_okay == dio) {
    if (2 <= nrrdStateVerboseIO) {
      fprintf(stderr, "with direct I/O ... ");
    }
    ret = airDioRead(fd, data, bsize);
    if (ret != bsize) {
      biffAddf(NRRD, "%s: airDioRead got read only "
               _AIR_SIZE_T_CNV " of " _AIR_SIZE_T_CNV " bytes "
               "(%g%% of expected)", me,
               ret, bsize, 100.0*ret/bsize);
      return 1;
    }
  } else {
    if (2 <= nrrdStateVerboseIO) {
      if (AIR_DIO && nio->format->usesDIO) {
        fprintf(stderr, "with fread(), not DIO: %s ...", airNoDioErr(dio));
      }
    }

    /* HEY: There's a bug in fread/fwrite in gcc 4.2.1 (with SnowLeopard).
            When it reads/writes a >=2GB data array, it pretends to succeed
            (i.e. the return value is the right number) but it hasn't
            actually read/written the data.  The work-around is to loop
            over the data, reading/writing 1GB (or smaller) chunks.         */
    ret = 0;
    data_c = (char *)data;
    elementSize = nrrdElementSize(nrrd);
    maxChunkSize = 1024 * 1024 * 1024 / elementSize;
    while(ret < elementNum) {
      remainder = elementNum-ret;
      if (remainder < maxChunkSize) {
	chunkSize = remainder;
      } else {
	chunkSize = maxChunkSize;
      }
      retTmp = 
	fread(&(data_c[ret*elementSize]), elementSize, chunkSize, file);
      ret += retTmp;
      if (retTmp != chunkSize) {
	biffAddf(NRRD, "%s: fread got read only "
                 _AIR_SIZE_T_CNV " " _AIR_SIZE_T_CNV "-sized things, not "
                 _AIR_SIZE_T_CNV " (%g%% of expected)", me,
                 ret, nrrdElementSize(nrrd), elementNum,
                 100.0*ret/elementNum);
	return 1;
      }
    }
    /* HEY: Here's the old version of the above code. 
    ret = fread(data, nrrdElementSize(nrrd), elementNum, file);
    if (ret != elementNum) {
      biffAddf(NRRD, "%s: fread got read only "
               _AIR_SIZE_T_CNV " " _AIR_SIZE_T_CNV "-sized things, not "
               _AIR_SIZE_T_CNV " (%g%% of expected)", me,
               ret, nrrdElementSize(nrrd), elementNum,
               100.0*ret/elementNum);
      return 1;
    }
    */

    car = fgetc(file);
    if (1 <= nrrdStateVerboseIO && EOF != car) {
      fprintf(stderr, "%s: WARNING: finished reading raw data, "
              "but file not at EOF\n", me);
      ungetc(car, file);
    }
    if (2 <= nrrdStateVerboseIO && nio->byteSkip && stdin != file) {
      savePos = ftell(file);
      if (!fseek(file, 0, SEEK_END)) {
        fprintf(stderr, "(%s: used %g%% of file for nrrd data)\n",
                me, 100.0*bsize/(ftell(file) + 1));
        fseek(file, savePos, SEEK_SET);
      }
    }
  }

  return 0;
}
Example #6
0
int
_nrrdEncodingRaw_write(FILE *file, const void *data, size_t elementNum,
                       const Nrrd *nrrd, NrrdIoState *nio) {
  static const char me[]="_nrrdEncodingRaw_write";
  int fd, dio;
  size_t ret, bsize;
  char *data_c;
  size_t elementSize, maxChunkSize, remainder, chunkSize;
  size_t retTmp;
  
  bsize = nrrdElementSize(nrrd)*elementNum;
  if (nio->format->usesDIO) {
    fd = fileno(file);
    dio = airDioTest(fd, data, bsize);
  } else {
    fd = -1;
    dio = airNoDio_format;
  }
  if (airNoDio_okay == dio) {
    if (2 <= nrrdStateVerboseIO) {
      fprintf(stderr, "with direct I/O ... ");
    }
    ret = airDioWrite(fd, data, bsize);
    if (ret != bsize) {
      biffAddf(NRRD, "%s: airDioWrite wrote only "
               _AIR_SIZE_T_CNV " of " _AIR_SIZE_T_CNV " bytes "
               "(%g%% of expected)", me,
               ret, bsize, 100.0*ret/bsize);
      return 1;
    }
  } else {
    if (2 <= nrrdStateVerboseIO) {
      if (AIR_DIO && nio->format->usesDIO) {
        fprintf(stderr, "with fread(), not DIO: %s ...", airNoDioErr(dio));
      }
    }

    /* HEY: There's a bug in fread/fwrite in gcc 4.2.1 (with SnowLeopard).
            When it reads/writes a >=2GB data array, it pretends to succeed
            (i.e. the return value is the right number) but it hasn't
            actually read/written the data.  The work-around is to loop
            over the data, reading/writing 1GB (or smaller) chunks.         */
    ret = 0;
    data_c = (char *)data;
    elementSize = nrrdElementSize(nrrd);
    maxChunkSize = 1024 * 1024 * 1024 / elementSize;
    while(ret < elementNum) {
      remainder = elementNum-ret;
      if (remainder < maxChunkSize) {
	chunkSize = remainder;
      } else {
	chunkSize = maxChunkSize;
      }
      retTmp = 
	fwrite(&(data_c[ret*elementSize]), elementSize, chunkSize, file);
      ret += retTmp;
      if (retTmp != chunkSize) {
	biffAddf(NRRD, "%s: fwrite wrote only "
                 _AIR_SIZE_T_CNV " " _AIR_SIZE_T_CNV "-sized things, not "
                 _AIR_SIZE_T_CNV " (%g%% of expected)", me,
                 ret, nrrdElementSize(nrrd), elementNum,
                 100.0*ret/elementNum);
	return 1;
      }
    }
    /* HEY: Here's the old version of the above code.
    ret = fwrite(data, nrrdElementSize(nrrd), elementNum, file);
    if (ret != elementNum) {
      biffAddf(NRRD, "%s: fwrite wrote only "
               _AIR_SIZE_T_CNV " " _AIR_SIZE_T_CNV "-sized things, not " 
               _AIR_SIZE_T_CNV " (%g%% of expected)", me,
               ret, nrrdElementSize(nrrd), elementNum,
               100.0*ret/elementNum);
      return 1;
    }
    */

    fflush(file);
    /*
    if (ferror(file)) {
      biffAddf(NRRD, "%s: ferror returned non-zero", me);
      return 1;
    }
    */
  }
  return 0;
}
Example #7
0
int
_nrrdEncodingRaw_read(FILE *file, void *data, size_t elementNum,
                      Nrrd *nrrd, NrrdIoState *nio) {
  char me[]="_nrrdEncodingRaw_read", err[BIFF_STRLEN];
  size_t ret, bsize;
  int fd, dio, car;
  long savePos;

  bsize = nrrdElementSize(nrrd)*elementNum;
  if (nio->format->usesDIO) {
    fd = fileno(file);
    dio = airDioTest(fd, data, bsize);
  } else {
    fd = -1;
    dio = airNoDio_format;
  }
  if (airNoDio_okay == dio) {
    if (2 <= nrrdStateVerboseIO) {
      fprintf(stderr, "with direct I/O ... ");
    }
    ret = airDioRead(fd, data, bsize);
    if (ret != bsize) {
      sprintf(err, "%s: airDioRead got read only "
              _AIR_SIZE_T_CNV " of " _AIR_SIZE_T_CNV " bytes "
              "(%g%% of expected)", me,
              ret, bsize, 100.0*ret/bsize);
      biffAdd(NRRD, err); return 1;
    }
  } else {
    if (2 <= nrrdStateVerboseIO) {
      if (AIR_DIO && nio->format->usesDIO) {
        fprintf(stderr, "with fread(), not DIO: %s ...", airNoDioErr(dio));
      }
    }
    ret = fread(data, nrrdElementSize(nrrd), elementNum, file);
    if (ret != elementNum) {
      sprintf(err, "%s: fread got read only "
              _AIR_SIZE_T_CNV " " _AIR_SIZE_T_CNV "-sized things, not "
              _AIR_SIZE_T_CNV " (%g%% of expected)", me,
              ret, nrrdElementSize(nrrd), elementNum,
              100.0*ret/elementNum);
      biffAdd(NRRD, err); return 1;
    }
    car = fgetc(file);
    if (1 <= nrrdStateVerboseIO && EOF != car) {
      fprintf(stderr, "%s: WARNING: finished reading raw data, "
              "but file not at EOF\n", me);
      ungetc(car, file);
    }
    if (2 <= nrrdStateVerboseIO && nio->byteSkip && stdin != file) {
      savePos = ftell(file);
      if (!fseek(file, 0, SEEK_END)) {
        fprintf(stderr, "(%s: used %g%% of file for nrrd data)\n",
                me, 100.0*bsize/(ftell(file) + 1));
        fseek(file, savePos, SEEK_SET);
      }
    }
  }

  return 0;
}
int
main(int argc, char *argv[]) {
#if TEEM_DIO == 0

  AIR_UNUSED(argc);
  fprintf(stderr, "%s: no direct-io testing for you\n", argv[0]);
  return 1;
#else 
  char *me, *fname, *multS, *data;
  FILE *file;
  double time0, time1, time2;
  int fd, align, mult, min, max, ret;
  size_t size;
  airArray *mop;

  me = argv[0];
  if (3 != argc) {
    /*                      0      1         2    (3) */
    fprintf(stderr, "usage: %s <filename> <mult>\n", me);
    return 1;
  }
  fname = argv[1];
  multS = argv[2];
  if (1 != sscanf(multS, "%d", &mult)) {
    fprintf(stderr, "%s: couln't parse mult %s as int\n", me, multS);
    return 1;
  }

  mop = airMopNew();
  if (!(file = fopen(fname, "w"))) {
    fprintf(stderr, "%s: couldn't open %s for writing\n", me, fname);
    airMopError(mop); return 1;
  }
  airMopAdd(mop, file, (airMopper)airFclose, airMopAlways);
  fd = fileno(file);
  if (-1 == fd) {
    fprintf(stderr, "%s: couldn't get underlying descriptor\n", me);
    airMopError(mop); return 1;
  }
  fprintf(stderr, "%s: fd(%s) = %d\n", me, fname, fd);

  ret = airDioTest(fd, NULL, 0);
  if (airNoDio_okay != ret) {
    fprintf(stderr, "%s: no good: \"%s\"\n", me, airNoDioErr(ret));
    airMopError(mop); return 1;
  }

  airDioInfo(&align, &min, &max, fd);
  fprintf(stderr, "%s: --> align=%d, min=%d, max=%d\n", me, align, min, max);
  size = (size_t)max*mult;
  data = airDioMalloc(size, fd);
  if (!data) {
    fprintf(stderr, "%s: airDioMalloc(" _AIR_SIZE_T_CNV ") failed\n", me,
            size);
    airMopError(mop); return 1;
  }
  airMopAdd(mop, data, airFree, airMopAlways);
  fprintf(stderr, "\ndata size = %g MB\n", (double)size/(1024*1024));
  
  /* -------------------------------------------------------------- */
  fprintf(stderr, "(1) non-aligned memory, regular write:\n");
  time0 = airTime();
  if (size-1 != write(fd, data+1, size-1)) {
    fprintf(stderr, "%s: write failed\n", me);
    airMopError(mop); return 1;
  }
  time1 = airTime();
  fsync(fd);
  time2 = airTime();
  fprintf(stderr, "   time = %g + %g = %g (%g MB/sec)\n",
          time1 - time0, time2 - time1, time2 - time0,
          (size/(1024*1024)) / (time2 - time0));
  airMopSub(mop, file, (airMopper)airFclose);
  fclose(file);
  /* -------------------------------------------------------------- */
  /* -------------------------------------------------------------- */
  fprintf(stderr, "(2) aligned memory, regular write:\n");
  file = fopen(fname, "w");
  airMopAdd(mop, file, (airMopper)airFclose, airMopAlways);
  fd = fileno(file);

  time0 = airTime();
  if (size != write(fd, data, size)) {
    fprintf(stderr, "%s: write failed\n", me);
    airMopError(mop); return 1;
  }
  time1 = airTime();
  fsync(fd);
  time2 = airTime();
  fprintf(stderr, "   time = %g + %g = %g (%g MB/sec)\n",
          time1 - time0, time2 - time1, time2 - time0,
          (size/(1024*1024)) / (time2 - time0));
  airMopSub(mop, file, (airMopper)airFclose);
  fclose(file);
  /* -------------------------------------------------------------- */
  /* -------------------------------------------------------------- */
  fprintf(stderr, "(3) aligned memory, air's direct IO:\n");
  file = fopen(fname, "w");
  airMopAdd(mop, file, (airMopper)airFclose, airMopAlways);
  fd = fileno(file);

  time0 = airTime();
  if (size != airDioWrite(fd, data, size)) {
    fprintf(stderr, "%s: write failed\n", me);
    airMopError(mop); return 1;
  }
  time1 = airTime();
  fsync(fd);
  time2 = airTime();
  fprintf(stderr, "   time = %g + %g = %g (%g MB/sec)\n",
          time1 - time0, time2 - time1, time2 - time0,
          (size/(1024*1024)) / (time2 - time0));
  airMopSub(mop, file, (airMopper)airFclose);
  fclose(file);
  /* -------------------------------------------------------------- */
  /* -------------------------------------------------------------- */
  fprintf(stderr, "(4) aligned memory, direct IO by hand:\n");
  {
    /* "input": fname, size, data */
    int flags;
    struct dioattr dio;
    char *ptr;
    size_t remain, totalrit, rit, part;

    file = fopen(fname, "w");
    if (-1 == (fd = fileno(file))) {
      fprintf(stderr, "%s: couldn't get underlying descriptor\n", me);
      airMopError(mop); return 1;
    }
    airMopAdd(mop, file, (airMopper)airFclose, airMopAlways);

    flags = fcntl(fd, F_GETFL);
    if (-1 == fcntl(fd, F_SETFL, flags | FDIRECT)) {
      fprintf(stderr, "%s: couldn't turn on direct IO\n", me);
      airMopError(mop); return 1;
    }
    if (0 != fcntl(fd, F_DIOINFO, &dio)) {
      fprintf(stderr, "%s: couldn't learn direct IO specifics", me);
      airMopError(mop); return 1;
    }
    
    remain = size;
    totalrit = 0;
    ptr = data;
    time0 = airTime();
    do {
      part = remain > dio.d_maxiosz ? dio.d_maxiosz : remain;
      rit = write(fd, ptr, part);
      if (rit != part) {
        fprintf(stderr, "%s: write failed\n", me);
        airMopError(mop); return 1;
      }
      totalrit += rit;
      ptr += rit;
      remain -= rit;
    } while (remain);
    time1 = airTime();
    fsync(fd);
    time2 = airTime();
    fprintf(stderr, "   time = %g + %g = %g (%g MB/sec)\n",
            time1 - time0, time2 - time1, time2 - time0,
            (size/(1024*1024)) / (time2 - time0));
    airMopSub(mop, file, (airMopper)airFclose);
    fclose(file);
  }
  /* -------------------------------------------------------------- */

  airMopError(mop); 
  exit(0);
#endif
}