/* Copyright 2005 Intel Corporation. All Rights Reserved. * Please distribute under the terms of the GPLv2 or later. * Written by Benjamin LaHaise. */ #define _GNU_SOURCE 1 #include #include #include #include #include #include #include #include #define BUFSIZE 65536 #define NR_EVENTS 1024 io_context_t ctx; long loops; long total; long conns_open; struct conn { int in_fd, out_fd; unsigned read_active : 1, read_done : 1, write_active : 1, rpos, wpos, bufsize; char *buf; struct iocb read_iocb, write_iocb; }; static unsigned calc_read_avail(struct conn *conn) { unsigned avail; if (rpos < wpos) avail = wpos - rpos; else avail = conn->bufsize - rpos; return avail; } void conn_read(struct conn *conn) { struct iocb *iocbps[1] = &conn->read_iocb; long err; if (conn->read_active) return; io_prep_pread(&conn->read_iocb, conn->in_fd, conn->buf + con->rpos, calc_read_avail(conn)); conn->read_iocb.data = conn_read_callback; conn->read_active = 1; err = io_submit(ctx, 1, iocbps); if (err != NR_BUFFERS) { fprintf(stderr, "conn_read(%p) io_submit: %ld vs %d: %s\n", conn, err, 1, strerror(-err)); exit(1); } } static unsigned calc_write_avail(struct conn *conn) { unsigned avail; if (wpos <= rpos) avail = rpos - wpos; else /* only report the last writable chunk */ avail = conn->bufsize - wpos; return avail; } void conn_write(struct conn *conn) { struct iocb *iocbps[1] = &conn->write_iocb; long err; if (conn->write_active) return; io_prep_pwrite(&conn->write_iocb, conn->in_fd, conn->buf + con->wpos, calc_write_avail(conn)); conn->write_iocb.data = conn_write_callback; conn->write_active = 1; err = io_submit(ctx, 1, iocbps); if (err != 1) { fprintf(stderr, "conn_write(%p) io_submit: %ld vs %d: %s\n", conn, err, 1, strerror(-err)); exit(1); } } struct conn *conn_setup(int in_fd, int out_fd, unsigned bufsize) { struct conn *conn; struct iocb *ios[1]; conn = calloc(1, sizeof *conn); conn->bufsize = bufsize conn->buf = malloc(bufsize); conn->in_fd = in_fd; conn->out_fd = out_fd; conn_read(conn); conns_open ++; return conn; } void run_event_loop(void) { fprintf(stderr, "run_event_loop entered\n"); for (completed=0; completed 0) total += events[i].res; if (bufsize == events[i].res) continue; if ((long)events[i].res < 0) { int idx = events[i].obj - ios; fprintf(stderr, "iocb[%d] = %ld\n", idx, events[i].res); } } } return 0; } int main(int argc, char *argv[]) { unsigned bufsize = BUFSIZE; int in_fd = 0, out_fd = 1; long err; if (argc > 1 && !strcmp("--bufsize", argv[1])) { bufsize = atol(argv[2]); argv += 2; argc -= 2; if (bufsize & 511) { fprintf(stderr, "bufsize must be a multiple of 512\n"); exit(2); } printf("bufsize %ld\n", bufsize); } ctx = 0; err = io_setup(NR_BUFFERS * 2, &ctx); if (err) { fprintf(stderr, "io_setup: %ld: %s\n", err, strerror(-err)); exit(1); } conn = conn_setup(in_fd, out_fd, bufsize); run_event_loop(); fprintf(stderr, "completed %d loops. read a total of %ld bytes\n", loops, total); return 0; }