Fio Windows update
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
diff --git a/engines/windowsaio.c b/engines/windowsaio.c
index 5c9d85e..849ae41 100644
--- a/engines/windowsaio.c
+++ b/engines/windowsaio.c
@@ -3,7 +3,6 @@
* Copyright (C) 2010 Bruce Cran <bruce@cran.org.uk>
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -17,6 +16,8 @@
struct windowsaio_data {
struct io_u **aio_events;
+ HANDLE *busyIoHandles;
+ unsigned int busyIo;
unsigned int ioFinished;
BOOL running;
BOOL stopped;
@@ -36,7 +37,6 @@
static void PrintError(LPCSTR lpszFunction);
static int fio_windowsaio_cancel(struct thread_data *td,
struct io_u *io_u);
-static DWORD GetEndCount(DWORD startCount, struct timespec *t);
static BOOL TimedOut(DWORD startCount, DWORD endCount);
static int fio_windowsaio_getevents(struct thread_data *td, unsigned int min,
unsigned int max, struct timespec *t);
@@ -84,25 +84,11 @@
return rc;
}
-static DWORD GetEndCount(DWORD startCount, struct timespec *t)
-{
- DWORD endCount = startCount;
-
- if (t == NULL)
- return 0;
-
- endCount += (t->tv_sec * 1000) + (t->tv_nsec / 1000000);
- return endCount;
-}
-
static BOOL TimedOut(DWORD startCount, DWORD endCount)
{
BOOL expired = FALSE;
DWORD currentTime;
- if (startCount == 0 || endCount == 0)
- return FALSE;
-
currentTime = GetTickCount();
if ((endCount > startCount) && currentTime >= endCount)
@@ -110,9 +96,6 @@
else if (currentTime < startCount && currentTime > endCount)
expired = TRUE;
- if (windowsaio_debug)
- printf("windowsaio: timedout = %d\n", expired);
-
return expired;
}
@@ -126,16 +109,16 @@
DWORD startCount = 0, endCount = 0;
BOOL timedout = FALSE;
unsigned int r = 0;
-
- if (windowsaio_debug)
- printf("getevents (min %d, max %d)\n", min, max);
+ unsigned int waitInMs = 100;
if (t != NULL) {
+ waitInMs = (t->tv_sec * 1000) + (t->tv_nsec / 1000000);
startCount = GetTickCount();
- endCount = GetEndCount(startCount, t);
+ endCount = startCount + (t->tv_sec * 1000) + (t->tv_nsec / 1000000);
}
while (dequeued < min && !timedout) {
+ WaitForMultipleObjects(wd->busyIo, wd->busyIoHandles, FALSE, waitInMs);
flist_for_each(entry, &td->io_u_busylist) {
io_u = flist_entry(entry, struct io_u, list);
@@ -149,23 +132,16 @@
wd->aio_events[r] = io_u;
r++;
- if (windowsaio_debug)
- printf("dequeued %d\n", dequeued);
+ wd->busyIo--;
if (dequeued == max)
break;
}
- if (TimedOut(startCount, endCount))
+ if (t != NULL && TimedOut(startCount, endCount))
timedout = TRUE;
-
- if (dequeued < min && !timedout)
- Sleep(250);
}
- if (windowsaio_debug)
- printf("leave getevents (%d)\n", dequeued);
-
return dequeued;
}
@@ -185,12 +161,11 @@
fio_ro_check(td, io_u);
- if (windowsaio_debug)
- printf("enqueue enter\n");
-
fov = malloc(sizeof(FIO_OVERLAPPED));
ZeroMemory(fov, sizeof(FIO_OVERLAPPED));
+ struct windowsaio_data *wd = td->io_ops->data;
+
io_u->seen = 0;
fov->o.Offset = io_u->offset & 0xFFFFFFFF;
@@ -224,6 +199,7 @@
io_u->error = 0;
rc = FIO_Q_COMPLETED;
} else if (!bSuccess && GetLastError() == ERROR_IO_PENDING) {
+ wd->busyIoHandles[wd->busyIo++] = fov->o.hEvent;
rc = FIO_Q_QUEUED;
} else {
PrintError(__func__);
@@ -232,9 +208,6 @@
rc = FIO_Q_COMPLETED;
}
- if (windowsaio_debug)
- printf("enqueue - leave (offset %llu)\n", io_u->offset);
-
return rc;
}
@@ -242,25 +215,22 @@
{
struct windowsaio_data *wd;
- if (windowsaio_debug)
- printf("windowsaio: cleanup - enter\n");
-
wd = td->io_ops->data;
wd->running = FALSE;
while (wd->stopped == FALSE)
- Sleep(5);
+ Sleep(20);
if (wd != NULL) {
CloseHandle(wd->hThread);
+
free(wd->aio_events);
- wd->aio_events = NULL;
+ free(wd->busyIoHandles);
free(wd);
+
td->io_ops->data = NULL;
}
- if (windowsaio_debug)
- printf("windowsaio: cleanup - leave\n");
}
static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter)
@@ -280,14 +250,8 @@
wd = ctx->wd;
bSuccess = TRUE;
- if (windowsaio_debug)
- printf("windowsaio: IoCompletionRoutine - enter\n");
-
while (ctx->wd->running) {
- bSuccess = GetQueuedCompletionStatus(ctx->ioCP, &bytes, &ulKey, &ovl, 500);
-
- if (windowsaio_debug)
- printf("GetQueuedCompletionStatus returned %d\n", bSuccess);
+ bSuccess = GetQueuedCompletionStatus(ctx->ioCP, &bytes, &ulKey, &ovl, 100);
if (!bSuccess) {
if (GetLastError() == WAIT_TIMEOUT) {
@@ -301,13 +265,6 @@
fov = CONTAINING_RECORD(ovl, FIO_OVERLAPPED, o);
io_u = fov->io_u;
- if (windowsaio_debug) {
- if (io_u->seen == 1)
- printf("IoCompletionRoutine - got already completed IO\n");
- else
- printf("IoCompletionRoutine - completed %d IO\n", ctx->wd->ioFinished);
- }
-
if (io_u->seen == 1)
continue;
@@ -330,9 +287,6 @@
if (!bSuccess)
PrintError(__func__);
- if (windowsaio_debug)
- printf("windowsaio: IoCompletionRoutine - leave\n");
-
ctx->wd->stopped = TRUE;
free(ctx);
return 0;
@@ -340,20 +294,36 @@
static int fio_windowsaio_init(struct thread_data *td)
{
- int rc = 0;
struct windowsaio_data *wd;
- if (windowsaio_debug)
- printf("windowsaio: init\n");
-
wd = malloc(sizeof(struct windowsaio_data));
+ if (wd == NULL)
+ return 1;
- ZeroMemory(wd, sizeof(*wd));
wd->aio_events = malloc((td->o.iodepth + 1) * sizeof(struct io_u *));
+ if (wd->aio_events == NULL) {
+ free(wd);
+ return 1;
+ }
+
+ wd->busyIoHandles = malloc((td->o.iodepth + 1) * sizeof(struct io_u *));
+ if (wd->busyIoHandles == NULL) {
+ free(wd->aio_events);
+ free(wd);
+ return 1;
+ }
+
ZeroMemory(wd->aio_events, (td->o.iodepth + 1) * sizeof(struct io_u *));
+ ZeroMemory(wd->busyIoHandles, (td->o.iodepth + 1) * sizeof(struct io_u *));
+
+ wd->busyIo = 0;
+ wd->ioFinished = 0;
+ wd->running = FALSE;
+ wd->stopped = FALSE;
+ wd->hThread = FALSE;
td->io_ops->data = wd;
- return rc;
+ return 0;
}
static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f)
@@ -367,9 +337,6 @@
dprint(FD_FILE, "fd open %s\n", f->file_name);
- if (windowsaio_debug)
- printf("windowsaio: open file %s - enter\n", f->file_name);
-
if (f->filetype == FIO_TYPE_PIPE) {
log_err("fio: windowsaio doesn't support pipes\n");
return 1;
@@ -439,9 +406,6 @@
}
}
- if (windowsaio_debug)
- printf("windowsaio: open file - leave (%d)\n", rc);
-
return rc;
}
@@ -449,9 +413,6 @@
{
BOOL bSuccess;
- if (windowsaio_debug)
- printf("windowsaio: close file\n");
-
if (f->hFile != INVALID_HANDLE_VALUE) {
bSuccess = CloseHandle(f->hFile);
if (!bSuccess)
diff --git a/os/os-windows.h b/os/os-windows.h
index 74c0f9e..f7712a1 100644
--- a/os/os-windows.h
+++ b/os/os-windows.h
@@ -1,7 +1,6 @@
#ifndef FIO_OS_WINDOWS_H
#define FIO_OS_WINDOWS_H
-
#include <sys/types.h>
#include <errno.h>
#include <windows.h>
@@ -51,7 +50,6 @@
*bytes = info.Length.QuadPart;
else
rc = EIO;
- }
/* If we were passed a POSIX fd,
* close the HANDLE we created via CreateFile */
@@ -66,14 +64,10 @@
return blockdev_size(f, bytes);
}
-{
-
static inline int blockdev_invalidate_cache(struct fio_file *f)
{
- BOOL bSuccess = FlushFileBuffers(f->hFile);
- if (!bSuccess)
- log_info("blockdev_invalidate_cache - FlushFileBuffers failed\n");
-
+ /* There's no way to invalidate the cache in Windows
+ * so just pretend to succeed */
return 0;
}
@@ -95,5 +89,4 @@
#define FIO_MADV_FREE MADV_FREE
#endif
-
#endif /* FIO_OS_WINDOWS_H */