diff --git a/benchmark/bench.cc b/benchmark/bench.cc index 6ac1bf5..09a4ccf 100644 --- a/benchmark/bench.cc +++ b/benchmark/bench.cc @@ -171,11 +171,11 @@ next_read_request(struct random_data *rdata) } res; random_r(rdata, &res.r[0]); random_r(rdata, &res.r[1]); - // random file descriptor from those opened - size_t i = (res.val & (BUFSIZE - 1)) % _files.size(); + // use the low order bits to pick a random file descriptor and length from those opened + size_t i = (size_t)((res.val & (BUFSIZE - 1)) % (uint64_t)(_files.size())); pair f = _files[i]; - // random offset with BUFSIZE alignment - f.second = ((res.val & ~(BUFSIZE - 1)) % f.second); + // use the high order bits as a random offset with BUFSIZE alignment within the length of the file + f.second = (off_t)((res.val & ~(BUFSIZE - 1)) % (uint64_t)(f.second)); return f; } diff --git a/ioqueue.c b/ioqueue.c index 54222db..36840c7 100644 --- a/ioqueue.c +++ b/ioqueue.c @@ -46,7 +46,11 @@ /* the request eventfd */ #define IOCB_RESFD(iocbp) (*(int*)&((iocbp)->aio_resfd)) /* the event closure data */ -#define IOEV_DATA(ioev) (*(void**)&(ioev)->data) +#define IOEV_DATA(ioev) (*(void**)&((ioev)->data)) +/* the event result code */ +#define IOEV_RESULT(ioev) (*(ssize_t*)&((ioev)->res)) +/* the event error code */ +#define IOEV_ERROR(ioev) (*(int*)&((ioev)->res2)) /* KAIO syscalls - wrappers provided by libaio */ extern int io_setup(unsigned depth, aio_context_t *ctxp); @@ -232,7 +236,8 @@ static int ioqueue_submit(unsigned int *nerr) unsigned int i, n; int ret; for (i = 0, n = 0; i < _nwait;) { - ret = io_submit(_ctx, _nwait - i, _io_reqs + i); + const long requestCount = (long)(_nwait - i); + ret = io_submit(_ctx, requestCount, _io_reqs + i); if (ret < 0) { if (-ret == EBADF) { /* head of the queue is bad, finish the request and continue */ @@ -240,7 +245,7 @@ static int ioqueue_submit(unsigned int *nerr) i ++; } else { /* ensure wait-queue occupies the head of the array */ - memmove(_io_reqs, _io_reqs + i, (size_t)(_nwait - i)); + memmove(_io_reqs, _io_reqs + i, (size_t)(requestCount)); _nwait -= i; errno = -ret; return -1; @@ -259,13 +264,13 @@ static int ioqueue_submit(unsigned int *nerr) } /* fetch and process any completed requests */ -int ioqueue_reap(unsigned int min) +int ioqueue_reap(unsigned int minRequestCount) { int ret, i; unsigned int nerr; /* cannot wait for more requests than have been allocated */ - if (_nfree == _nreqs || min > _nreqs || (unsigned int)min > _nreqs - _nfree) { + if (_nfree == _nreqs || minRequestCount > _nreqs || minRequestCount > _nreqs - _nfree) { errno = EINVAL; return -1; } @@ -276,12 +281,12 @@ int ioqueue_reap(unsigned int min) /* re-adjust minimum to account for EBADF-finished requests */ if (nerr > 0) { - min -= nerr; + minRequestCount -= nerr; } - /* block for at least 'min' completion events */ + /* block until at least the minimum number of requests have completed */ do { - ret = io_getevents(_ctx, min, _depth, _io_evs, NULL); + ret = io_getevents(_ctx, (long)(minRequestCount), (long)(_depth), _io_evs, NULL); } while (ret < 0 && errno == EINTR); if (ret < 0) { return ret; @@ -289,7 +294,12 @@ int ioqueue_reap(unsigned int min) /* finish the reaped requests */ for (i = 0; i < ret; i++) { - ioqueue_request_finish(IOEV_DATA(&_io_evs[i]), _io_evs[i].res, (int)_io_evs[i].res2); + const struct io_event *const event = &_io_evs[i]; + ioqueue_request_finish( + IOEV_DATA(event), + IOEV_RESULT(event), + IOEV_ERROR(event) + ); } /* return the number of completed requests */ return ret + (int)nerr;