From e4db9fec06d77523472e9fad6de5170a77d715c0 Mon Sep 17 00:00:00 2001 From: Bruce Cran Date: Tue, 4 Jan 2011 14:44:47 +0100 Subject: [PATCH] Fio Windows update Signed-off-by: Jens Axboe --- engines/windowsaio.c | 115 ++++++++++++++----------------------------- os/os-windows.h | 11 +---- 2 files changed, 40 insertions(+), 86 deletions(-) diff --git a/engines/windowsaio.c b/engines/windowsaio.c index 5c9d85e1..849ae41b 100644 --- a/engines/windowsaio.c +++ b/engines/windowsaio.c @@ -3,7 +3,6 @@ * Copyright (C) 2010 Bruce Cran */ - #include #include #include @@ -17,6 +16,8 @@ BOOL windowsaio_debug = FALSE; struct windowsaio_data { struct io_u **aio_events; + HANDLE *busyIoHandles; + unsigned int busyIo; unsigned int ioFinished; BOOL running; BOOL stopped; @@ -36,7 +37,6 @@ struct thread_ctx { 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 @@ static int fio_windowsaio_cancel(struct thread_data *td, 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 @@ static BOOL TimedOut(DWORD startCount, DWORD endCount) else if (currentTime < startCount && currentTime > endCount) expired = TRUE; - if (windowsaio_debug) - printf("windowsaio: timedout = %d\n", expired); - return expired; } @@ -126,16 +109,16 @@ static int fio_windowsaio_getevents(struct thread_data *td, unsigned int min, 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 @@ static int fio_windowsaio_getevents(struct thread_data *td, unsigned int min, 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 @@ static int fio_windowsaio_queue(struct thread_data *td, 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 @@ static int fio_windowsaio_queue(struct thread_data *td, 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 @@ static int fio_windowsaio_queue(struct thread_data *td, rc = FIO_Q_COMPLETED; } - if (windowsaio_debug) - printf("enqueue - leave (offset %llu)\n", io_u->offset); - return rc; } @@ -242,25 +215,22 @@ static void fio_windowsaio_cleanup(struct thread_data *td) { 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 @@ static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter) 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 @@ static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter) 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 @@ static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter) 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 DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter) 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 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) 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 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) } } - if (windowsaio_debug) - printf("windowsaio: open file - leave (%d)\n", rc); - return rc; } @@ -449,9 +413,6 @@ static int fio_windowsaio_close_file(struct thread_data fio_unused *td, struct f { 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 74c0f9e8..f7712a17 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 #include #include @@ -51,7 +50,6 @@ static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) *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 @@ static inline int chardev_size(struct fio_file *f, unsigned long long *bytes) 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 @@ static inline void os_get_tmpdir(char *path, int len) #define FIO_MADV_FREE MADV_FREE #endif - #endif /* FIO_OS_WINDOWS_H */ -- 2.25.1