The following changes since commit b6f6abc689b3c05306bb1613a3d43f24fa4417d8: Switch mutex to using anonymous mmap (2011-05-02 10:10:56 -0600) are available in the git repository at: git://git.kernel.dk/fio.git master Bruce Cran (1): Windows fixes Jens Axboe (2): Bump max job count to 2048 Convert left-over manual ->runstate setting to td_set_runstate() engines/windowsaio.c | 125 +++++++++++++++++++++++------------------------- fio.h | 4 +- os/windows/cygwin.wxs | 16 ++++-- os/windows/dobuild.cmd | 8 ++-- 4 files changed, 76 insertions(+), 77 deletions(-) --- Diff of recent changes: diff --git a/engines/windowsaio.c b/engines/windowsaio.c index f66b9a2..2d3ed83 100644 --- a/engines/windowsaio.c +++ b/engines/windowsaio.c @@ -1,6 +1,6 @@ /* * Native Windows async IO engine - * Copyright (C) 2010 Bruce Cran <bruce@xxxxxxxxxxx> + * Copyright (C) 2011 Bruce Cran <bruce@xxxxxxxxxxx> */ #include <stdio.h> @@ -12,6 +12,8 @@ #include "../fio.h" +typedef BOOL (WINAPI *CANCELIOEX)(HANDLE hFile, LPOVERLAPPED lpOverlapped); + typedef struct { OVERLAPPED o; struct io_u *io_u; @@ -28,7 +30,8 @@ struct windowsaio_data { struct io_u **aio_events; HANDLE iocomplete_event; - BOOL have_cancelioex; + CANCELIOEX pCancelIoEx; + BOOL useIOCP; }; struct thread_ctx { @@ -51,14 +54,6 @@ static int fio_windowsaio_init(struct thread_data *td); static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f); static int fio_windowsaio_close_file(struct thread_data fio_unused *td, struct fio_file *f); -/* CancelIoEx isn't in Cygwin's w32api */ -BOOL WINAPI CancelIoEx( - HANDLE hFile, - LPOVERLAPPED lpOverlapped -); - - - int sync_file_range(int fd, off64_t offset, off64_t nbytes, unsigned int flags) { @@ -94,10 +89,10 @@ static int fio_windowsaio_cancel(struct thread_data *td, struct windowsaio_data *wd = td->io_ops->data; - /* If we're running on Vista, we can cancel individual IO requests */ - if (wd->have_cancelioex) { + /* If we're running on Vista or newer, we can cancel individual IO requests */ + if (wd->pCancelIoEx != NULL) { FIO_OVERLAPPED *ovl = io_u->engine_data; - if (!CancelIoEx(io_u->file->hFile, &ovl->o)) + if (!wd->pCancelIoEx(io_u->file->hFile, &ovl->o)) rc = 1; } else rc = 1; @@ -141,8 +136,8 @@ static int fio_windowsaio_getevents(struct thread_data *td, unsigned int min, flist_for_each(entry, &td->io_u_busylist) { io_u = flist_entry(entry, struct io_u, list); - if (io_u->seen == 1) { - io_u->seen = 2; + if (io_u->seen == 0) { + io_u->seen = 1; wd->aio_events[dequeued] = io_u; dequeued++; } @@ -151,9 +146,8 @@ static int fio_windowsaio_getevents(struct thread_data *td, unsigned int min, break; } - if (dequeued < min) { + if (dequeued < min) WaitForSingleObject(wd->iocomplete_event, mswait); - } if (t != NULL && TimedOut(start_count, end_count)) timedout = TRUE; @@ -172,6 +166,7 @@ static int fio_windowsaio_queue(struct thread_data *td, struct io_u *io_u) { struct windowsaio_data *wd; + LPOVERLAPPED lpOvl; DWORD iobytes; BOOL success = TRUE; int ind; @@ -183,40 +178,47 @@ static int fio_windowsaio_queue(struct thread_data *td, ind = wd->io_index; ResetEvent(wd->io_handles[ind]); - wd->ovls[ind].o.Internal = 0; - wd->ovls[ind].o.InternalHigh = 0; - wd->ovls[ind].o.Offset = io_u->offset & 0xFFFFFFFF; - wd->ovls[ind].o.OffsetHigh = io_u->offset >> 32; - wd->ovls[ind].o.hEvent = wd->io_handles[ind]; - wd->ovls[ind].io_u = io_u; + + if (wd->useIOCP) { + lpOvl = &wd->ovls[ind].o; + + lpOvl->Internal = STATUS_PENDING; + lpOvl->InternalHigh = 0; + lpOvl->Offset = io_u->offset & 0xFFFFFFFF; + lpOvl->OffsetHigh = io_u->offset >> 32; + lpOvl->hEvent = wd->io_handles[ind]; + lpOvl->Pointer = NULL; + wd->ovls[ind].io_u = io_u; + } else { + lpOvl = NULL; + } io_u->engine_data = &wd->ovls[ind]; io_u->seen = 0; if (io_u->ddir == DDIR_WRITE) { - success = WriteFile(io_u->file->hFile, io_u->xfer_buf, io_u->xfer_buflen, &iobytes, &wd->ovls[ind].o); + success = WriteFile(io_u->file->hFile, io_u->xfer_buf, io_u->xfer_buflen, &iobytes, lpOvl); } else if (io_u->ddir == DDIR_READ) { - success = ReadFile(io_u->file->hFile, io_u->xfer_buf, io_u->xfer_buflen, &iobytes, &wd->ovls[ind].o); + success = ReadFile(io_u->file->hFile, io_u->xfer_buf, io_u->xfer_buflen, &iobytes, lpOvl); } else if (io_u->ddir == DDIR_SYNC || - io_u->ddir == DDIR_DATASYNC || - io_u->ddir == DDIR_SYNC_FILE_RANGE) + io_u->ddir == DDIR_DATASYNC || + io_u->ddir == DDIR_SYNC_FILE_RANGE) { FlushFileBuffers(io_u->file->hFile); return FIO_Q_COMPLETED; } else if (io_u->ddir == DDIR_TRIM) { - log_info("explicit TRIM isn't supported on Windows"); + log_info("Manual TRIM isn't supported on Windows"); return FIO_Q_COMPLETED; } else assert(0); - if (success) { - io_u->seen = 1; + if (wd->useIOCP && (success || GetLastError() == ERROR_IO_PENDING)) { + wd->io_index = (wd->io_index + 1) % td->o.iodepth; + rc = FIO_Q_QUEUED; + } else if (success && !wd->useIOCP) { io_u->resid = io_u->xfer_buflen - iobytes; io_u->error = 0; rc = FIO_Q_COMPLETED; - } else if (!success && GetLastError() == ERROR_IO_PENDING) { - wd->io_index = (wd->io_index + 1) % (2 * td->o.iodepth); - rc = FIO_Q_QUEUED; } else { PrintError(__func__); io_u->error = GetLastError(); @@ -241,7 +243,7 @@ static void fio_windowsaio_cleanup(struct thread_data *td) CloseHandle(wd->iothread_stopped); CloseHandle(wd->iocomplete_event); - for (i = 0; i < 2 * td->o.iodepth; i++) { + for (i = 0; i < td->o.iodepth; i++) { CloseHandle(wd->io_handles[i]); } @@ -268,16 +270,13 @@ static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter) ctx = (struct thread_ctx*)lpParameter; wd = ctx->wd; - while (ctx->wd->iothread_running) { + do { if (!GetQueuedCompletionStatus(ctx->iocp, &bytes, &ulKey, &ovl, 250)) continue; fov = CONTAINING_RECORD(ovl, FIO_OVERLAPPED, o); io_u = fov->io_u; - if (io_u->seen != 0) - continue; - if (ovl->Internal == ERROR_SUCCESS) { io_u->resid = io_u->xfer_buflen - ovl->InternalHigh; io_u->error = 0; @@ -286,9 +285,8 @@ static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter) io_u->error = ovl->Internal; } - io_u->seen = 1; SetEvent(wd->iocomplete_event); - } + } while (ctx->wd->iothread_running); CloseHandle(ctx->iocp); SetEvent(ctx->wd->iothread_stopped); @@ -300,7 +298,7 @@ static DWORD WINAPI IoCompletionRoutine(LPVOID lpParameter) static int fio_windowsaio_init(struct thread_data *td) { struct windowsaio_data *wd; - OSVERSIONINFO osInfo; + HANDLE hKernel32Dll; int rc = 0; wd = malloc(sizeof(struct windowsaio_data)); @@ -316,13 +314,13 @@ static int fio_windowsaio_init(struct thread_data *td) } if (!rc) { - wd->io_handles = malloc(2 * td->o.iodepth * sizeof(HANDLE)); + wd->io_handles = malloc(td->o.iodepth * sizeof(HANDLE)); if (wd->io_handles == NULL) rc = 1; } if (!rc) { - wd->ovls = malloc(2 * td->o.iodepth * sizeof(FIO_OVERLAPPED)); + wd->ovls = malloc(td->o.iodepth * sizeof(FIO_OVERLAPPED)); if (wd->ovls == NULL) rc = 1; } @@ -334,16 +332,6 @@ static int fio_windowsaio_init(struct thread_data *td) rc = 1; } - if (!rc) { - osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osInfo); - - if (osInfo.dwMajorVersion >= 6) - wd->have_cancelioex = TRUE; - else - wd->have_cancelioex = FALSE; - } - if (rc) { PrintError(__func__); if (wd != NULL) { @@ -358,6 +346,9 @@ static int fio_windowsaio_init(struct thread_data *td) } } + hKernel32Dll = GetModuleHandle("kernel32.dll"); + wd->pCancelIoEx = GetProcAddress(hKernel32Dll, "CancelIoEx"); + td->io_ops->data = wd; return 0; } @@ -366,7 +357,7 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) { int rc = 0; HANDLE hFile; - DWORD flags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_OVERLAPPED; + DWORD flags = FILE_FLAG_POSIX_SEMANTICS; DWORD sharemode = FILE_SHARE_READ | FILE_SHARE_WRITE; DWORD openmode = OPEN_ALWAYS; DWORD access; @@ -384,6 +375,9 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) return 1; } + if (!td->o.odirect && !td->o.sync_io && td->io_ops->data != NULL) + flags |= FILE_FLAG_OVERLAPPED; + if (td->o.odirect) flags |= FILE_FLAG_NO_BUFFERING; if (td->o.sync_io) @@ -391,17 +385,12 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) if (td->o.td_ddir == TD_DDIR_READ || - td->o.td_ddir == TD_DDIR_WRITE || - td->o.td_ddir == TD_DDIR_RANDRW) - { + td->o.td_ddir == TD_DDIR_WRITE) flags |= FILE_FLAG_SEQUENTIAL_SCAN; - } else - { flags |= FILE_FLAG_RANDOM_ACCESS; - } - if (td_read(td) || read_only) + if (!td_write(td) || read_only) access = GENERIC_READ; else access = (GENERIC_READ | GENERIC_WRITE); @@ -421,12 +410,18 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) /* Only set up the competion port and thread if we're not just * querying the device size */ - if (!rc && td->io_ops->data != NULL) { - struct windowsaio_data *wd; + if (!rc && td->io_ops->data != NULL && !td->o.odirect && !td->o.sync_io) { struct thread_ctx *ctx; + struct windowsaio_data *wd; hFile = CreateIoCompletionPort(f->hFile, NULL, 0, 0); - wd = td->io_ops->data; + + wd = td->io_ops->data; + + if (!td->o.odirect && !td->o.sync_io) + wd->useIOCP = 1; + else + wd->useIOCP = 0; wd->io_index = 0; wd->iothread_running = TRUE; @@ -437,7 +432,7 @@ static int fio_windowsaio_open_file(struct thread_data *td, struct fio_file *f) rc = 1; if (!rc) { - for (i = 0; i < 2 * td->o.iodepth; i++) { + for (i = 0; i < td->o.iodepth; i++) { /* Create a manual-reset event for putting in OVERLAPPED */ wd->io_handles[i] = CreateEvent(NULL, TRUE, FALSE, NULL); if (wd->io_handles[i] == NULL) { diff --git a/fio.h b/fio.h index c0087e8..6ad186f 100644 --- a/fio.h +++ b/fio.h @@ -557,7 +557,7 @@ static inline void fio_ro_check(struct thread_data *td, struct io_u *io_u) #define RAND_MAP_IDX(f, b) (TO_MAP_BLOCK(f, b) / BLOCKS_PER_MAP) #define RAND_MAP_BIT(f, b) (TO_MAP_BLOCK(f, b) & (BLOCKS_PER_MAP - 1)) -#define MAX_JOBS (1024) +#define MAX_JOBS (2048) #define td_non_fatal_error(e) ((e) == EIO || (e) == EILSEQ) @@ -666,7 +666,7 @@ extern int load_blktrace(struct thread_data *, const char *); if (!(cond)) { \ int *__foo = NULL; \ fprintf(stderr, "file:%s:%d, assert %s failed\n", __FILE__, __LINE__, #cond); \ - (td)->runstate = TD_EXITED; \ + td_set_runstate((td), TD_EXITED); \ (td)->error = EFAULT; \ *__foo = 0; \ } \ diff --git a/os/windows/cygwin.wxs b/os/windows/cygwin.wxs index f74b422..c33c133 100755 --- a/os/windows/cygwin.wxs +++ b/os/windows/cygwin.wxs @@ -24,11 +24,14 @@ <Component Id="cmp229D68D422FB0EB697971491C1475142" Guid="{027945EC-DA28-41C8-9AFF-7AE1BD0F7078}"> <File Id="fil7FD65A67872AB00D44EE1419EED402F3" KeyPath="yes" Source="fio\bin\cygintl-8.dll" /> </Component> - <Component Id="cmpFCBAB68E4A226C62E32EF283AA1ABC5A" Guid="{2FE224F7-DF14-4D19-8154-77BF6A81B895}"> - <File Id="filF29BC713B2D6CF3C73FAC7EBD9E7DA59" KeyPath="yes" Source="fio\bin\cygncurses++-9.dll" /> + <Component Id="cygncursespp_10" Guid="{02ecd011-d86c-4400-97b3-65dbcddbb5d9}"> + <File Id="cygncursespp_10" KeyPath="yes" Source="fio\bin\cygncurses++-10.dll" /> </Component> - <Component Id="cmp30425E1537382CBE87A8582C3712DA6D" Guid="{43895BDD-58DD-4EA9-96A2-A17EADD13C65}"> - <File Id="fil346312AAE49BBD0EDE977120B93991EE" KeyPath="yes" Source="fio\bin\cygncurses-9.dll" /> + <Component Id="cygncurses_10" Guid="{2ce11a26-c1d8-46d3-86ef-8545685a44b2}"> + <File Id="cygncurses_10" KeyPath="yes" Source="fio\bin\cygncurses-10.dll" /> + </Component> + <Component Id="cygncursesw_10" Guid="44fe569a-375f-4103-93e9-0dc4195efb89"> + <File Id="cygncursesw_10" KeyPath="yes" Source="fio\bin\cygncursesw-10.dll" /> </Component> <Component Id="cmp9B2CF01422C767668980462815CBD1FC" Guid="{55DD475C-5E0B-4C46-93BF-6D9E44B44CDC}"> <File Id="filC2E6ED6705CC982EC3E7FE8F1089AD7A" KeyPath="yes" Source="fio\bin\cygreadline7.dll" /> @@ -6408,6 +6411,7 @@ </Fragment> <Fragment> <ComponentGroup Id="cygwin"> + <ComponentRef Id="cygncursesw_10" /> <ComponentRef Id="cmpB647D75194B1BE4C7C89501B755FB631" /> <ComponentRef Id="cmp0632DB51E5BC3C2DABB6D68937C68C14" /> <ComponentRef Id="cmpB4B196A767932EB43E26C3FDB12F34A5" /> @@ -6415,8 +6419,8 @@ <ComponentRef Id="cmp426BE94F315430D90C59934ECCE4A484" /> <ComponentRef Id="cmpB233C0A559F9EB1AFE292982562F1ECC" /> <ComponentRef Id="cmp229D68D422FB0EB697971491C1475142" /> - <ComponentRef Id="cmpFCBAB68E4A226C62E32EF283AA1ABC5A" /> - <ComponentRef Id="cmp30425E1537382CBE87A8582C3712DA6D" /> + <ComponentRef Id="cygncursespp_10" /> + <ComponentRef Id="cygncurses_10" /> <ComponentRef Id="cmp9B2CF01422C767668980462815CBD1FC" /> <ComponentRef Id="cmpF04F051EF4B7C676F1989889D664CEBF" /> <ComponentRef Id="cmp6B8D3319D753D33FA084D14C712FFE56" /> diff --git a/os/windows/dobuild.cmd b/os/windows/dobuild.cmd index fa855a2..95543d7 100755 --- a/os/windows/dobuild.cmd +++ b/os/windows/dobuild.cmd @@ -1,4 +1,4 @@ -"%WIX%\bin\candle" cygwin.wxs -"%WIX%\bin\candle" install.wxs -"%WIX%\bin\candle" examples.wxs -"%WIX%\bin\light" install.wixobj cygwin.wixobj examples.wixobj -ext WixUIExtension -out fio.msi \ No newline at end of file +"%WIX%bin\candle" cygwin.wxs +"%WIX%bin\candle" install.wxs +"%WIX%bin\candle" examples.wxs +"%WIX%bin\light" install.wixobj cygwin.wixobj examples.wixobj -ext WixUIExtension -out fio.msi \ No newline at end of file -- To unsubscribe from this list: send the line "unsubscribe fio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html