コード例 #1
0
ファイル: zero_md0.c プロジェクト: nlm/zero_md0
void loop_aio(int fd, void *buf)
{
  int res;
  unsigned int elapsed;

  /* i/o context initialization */
  io_context_t myctx;
  memset(&myctx, 0, sizeof(myctx));
  if ((res = io_queue_init(maxinflight, &myctx)))
    io_error("io_queue_init", res);

  copied = 0;
  inflight = 0;

  if (opt_verbose)
    printf("[run %d] start\n", runid);

  while (copied < mycount)
  {
    struct iocb *ioq[maxsubmit];
    int tosubmit = 0;
    unsigned long long int index;
    struct iocb *iocb;
    struct timeval tv1, tv2;

    /* filling a context with io queries */
    while (copied + inflight + tosubmit < mycount &&
      inflight + tosubmit < maxinflight &&
      tosubmit < maxsubmit)
    {
      /* Simultaneous asynchronous operations using the same iocb produce undefined results. */
      iocb = calloc(1, sizeof(struct iocb));

      if (mode_rnd)
        index = (mydevsize / myiosize) * random() / RAND_MAX;
      else
        index = copied + inflight + tosubmit;

      if (mode_write)
        io_prep_pwrite(iocb, fd, buf, myiosize, index * myiosize);
      else
        io_prep_pread(iocb, fd, buf, myiosize, index * myiosize);

      io_set_callback(iocb, io_done);
      ioq[tosubmit] = iocb;
      tosubmit += 1;
    }

    /* if there are available slots for submitting queries, do it */
    if (tosubmit)
    {
      /* submit io and check elapsed time */
      gettimeofday(&tv1, NULL);
      if ((res = io_submit(myctx, tosubmit, ioq)) != tosubmit)
      {
        printf("only %d io submitted\n", res);
        io_error("io_submit write", res);
      }
      gettimeofday(&tv2, NULL);
      elapsed = (tv2.tv_sec - tv1.tv_sec) * 1000 + (tv2.tv_usec - tv1.tv_usec) / 1000;
      if (elapsed > 200)
        printf("warning: io_submit() took %d ms, this is suspicious, maybe nr_request is too low.\n", elapsed);

      /* inflight io += newly submitted io */
      inflight += tosubmit;
    }

    /* handle completed io events */
    if ((res = io_queue_run(myctx)) < 0)
      io_error("io_queue_run", res);

    if (inflight == maxinflight ||
      (inflight && copied + inflight == mycount))
    {
      struct io_event event;
      if ((res = io_getevents(myctx, 1, 1, &event, NULL)) < 0)
        io_error("io_getevents", res);
      if (res != 1)
        errx(1, "no events?");
      ((io_callback_t)event.obj->data)(myctx, event.obj, event.res, event.res2);
    }
  }

  io_queue_release(myctx);
}
コード例 #2
0
ファイル: aioread.c プロジェクト: xjtuwjp/farm
int
main(int argc, char *const *argv)
{
	int srcfd;
	struct stat st;
	off_t length = 0, offset = 0;
	io_context_t myctx;

	if (argc != 2 || argv[1][0] == '-') {
		fprintf(stderr, "Usage: aioread SOURCE");
		exit(1);
	}
	
	if ((srcfd = open(srcname = argv[1], O_RDONLY)) < 0) {
		perror(srcname);
		exit(1);
	}
	
	if (fstat(srcfd, &st) < 0) {
		perror("fstat");
		exit(1);
	}

	length = st.st_size;
	
	/* initialize state machine */
	memset(&myctx, 0, sizeof(myctx));
	io_queue_init(AIO_MAXIO, &myctx);
	tocopy = howmany(length, AIO_BLKSIZE);
	
	printf("tocopy: %ld times\n", tocopy);
	
	
	int i, j;
	for (i = 0; i < AIO_MAXIO; i ++)
		memset(&aiobuf[i], '\0', sizeof(struct mybuf));
	
	int ps = getpagesize();
	
	while (tocopy > 0) {
		rc;
	
		/* Submit as many reads as once as possible upto AIO_MAXIO */
		int n = MIN(MIN(AIO_MAXIO - busy, AIO_MAXIO / 2), \
			howmany(length - offset, AIO_BLKSIZE));
		
		if (n > 0) {
			struct iocb *ioq[n];

			for (i = 0; i < n; i++) {
				struct iocb *io = (struct iocb *) malloc(sizeof(struct iocb));
				int iosize = MIN(length - offset, AIO_BLKSIZE);
				
				for (j = 0; j < AIO_MAXIO; j ++) {
					
				}
				
				char *buf;
				
				posix_memalign(&buf, ps, iosize);
				if (NULL == buf || NULL == io) {
					fprintf(stderr, "out of memory\n");
					exit(1);
				}
				
				io_prep_pread(io, srcfd, buf, iosize, offset);
				io_set_callback(io, rd_done);
				
				ioq[i] = io;
				offset += iosize;
			}
		
			rc = io_submit(myctx, n, ioq);
			
			if (rc < 0)
				io_error("io_submit", rc);
			
			busy += n;
		}
		
		// Handle IO’s that have completed
		rc = io_queue_run(myctx);
		if (rc < 0)
			io_error("io_queue_run", rc);

		// if we have maximum number of i/o’s in flight
		// then wait for one to complete
		
		if (busy == AIO_MAXIO) {
			rc = io_queue_wait(myctx, NULL);
			if (rc < 0)
				io_error("io_queue_wait", rc);
		}
	}
	
	close(srcfd);
	
	exit(0);
}