The following changes since commit 48b35be009138ddca8d341f7767a1364400b6c06: Fix AIX Makefile (2011-07-13 20:28:07 +0200) are available in the git repository at: git://git.kernel.dk/fio.git master Bruce Cran (2): Add CPU affinity support to Windows Windows affinity fix for thread based jobs Jens Axboe (4): Fix compile warning on OSX Make raw disk size detection work on OSX Fix infinite loop on platforms with severely limited aio resources Fio 1.57 Michael Callahan (1): Fix killing of threads that haven't started Makefile | 3 +- fio.c | 15 ++++-- init.c | 2 +- os/os-mac.h | 15 ++++++ os/os-windows.h | 121 ++++++++++++++++++++++++++++++++++++++++++++++- os/windows/install.wxs | 2 +- os/windows/version.h | 4 +- 7 files changed, 149 insertions(+), 13 deletions(-) --- Diff of recent changes: diff --git a/Makefile b/Makefile index 17c6527..a80f4ca 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,8 @@ ifeq ($(UNAME), Darwin) endif ifneq (,$(findstring CYGWIN,$(UNAME))) SOURCE += engines/windowsaio.c - LIBS += -lpthread -lrt + LIBS += -lpthread -lrt -lpsapi + CFLAGS += -DPSAPI_VERSION=1 endif OBJS = $(SOURCE:.c=.o) diff --git a/fio.c b/fio.c index 2855ddf..120431e 100644 --- a/fio.c +++ b/fio.c @@ -102,7 +102,9 @@ static void terminate_threads(int group_id) /* * if the thread is running, just let it exit */ - if (td->runstate < TD_RAMP) + if (!td->pid) + continue; + else if (td->runstate < TD_RAMP) kill(td->pid, SIGTERM); else { struct ioengine_ops *ops = td->io_ops; @@ -548,9 +550,10 @@ sync_done: /* * if we can queue more, do so. but check if there are - * completed io_u's first. + * completed io_u's first. Note that we can get BUSY even + * without IO queued, if the system is resource starved. */ - full = queue_full(td) || ret == FIO_Q_BUSY; + full = queue_full(td) || (ret == FIO_Q_BUSY && td->cur_depth); if (full || !td->o.iodepth_batch_complete) { min_events = min(td->o.iodepth_batch_complete, td->cur_depth); @@ -708,9 +711,11 @@ sync_done: break; /* - * See if we need to complete some commands + * See if we need to complete some commands. Note that we + * can get BUSY even without IO queued, if the system is + * resource starved. */ - full = queue_full(td) || ret == FIO_Q_BUSY; + full = queue_full(td) || (ret == FIO_Q_BUSY && td->cur_depth); if (full || !td->o.iodepth_batch_complete) { min_evts = min(td->o.iodepth_batch_complete, td->cur_depth); diff --git a/init.c b/init.c index 94b2b77..85bd0f7 100644 --- a/init.c +++ b/init.c @@ -22,7 +22,7 @@ #include "lib/getopt.h" -static char fio_version_string[] = "fio 1.56"; +static char fio_version_string[] = "fio 1.57"; #define FIO_RANDSEED (0xb1899bedUL) diff --git a/os/os-mac.h b/os/os-mac.h index 0d3cae3..eb55cd7 100644 --- a/os/os-mac.h +++ b/os/os-mac.h @@ -8,6 +8,7 @@ #include <sys/time.h> #include <unistd.h> #include <signal.h> +#include <mach/mach_init.h> #include "../file.h" @@ -23,6 +24,7 @@ #define FIO_HAVE_CLOCK_MONOTONIC #define FIO_USE_GENERIC_RAND #define FIO_HAVE_GETTID +#define FIO_HAVE_CHARDEV_SIZE #define OS_MAP_ANON MAP_ANON @@ -134,6 +136,19 @@ static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) return 0; } +static inline int chardev_size(struct fio_file *f, unsigned long long *bytes) +{ + /* + * Could be a raw block device, this is better than just assuming + * we can't get the size at all. + */ + if (!blockdev_size(f, bytes)) + return 0; + + *bytes = -1ULL; + return 0; +} + static inline int blockdev_invalidate_cache(struct fio_file *f) { return EINVAL; diff --git a/os/os-windows.h b/os/os-windows.h index e790a51..db4127b 100644 --- a/os/os-windows.h +++ b/os/os-windows.h @@ -4,19 +4,21 @@ #include <sys/types.h> #include <errno.h> #include <windows.h> +#include <psapi.h> #include "../smalloc.h" #include "../file.h" #include "../log.h" #define FIO_HAVE_ODIRECT -#define FIO_USE_GENERIC_RAND +#define FIO_HAVE_CPU_AFFINITY #define FIO_HAVE_CHARDEV_SIZE -#define FIO_USE_GENERIC_RAND - #define FIO_HAVE_FALLOCATE #define FIO_HAVE_FDATASYNC #define FIO_HAVE_WINDOWSAIO +#define FIO_HAVE_GETTID + +#define FIO_USE_GENERIC_RAND #define OS_MAP_ANON MAP_ANON @@ -32,6 +34,8 @@ typedef struct { #define IOCTL_DISK_GET_LENGTH_INFO 0x7405C +pid_t cygwin_winpid_to_pid(int winpid); + static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) { int rc = 0; @@ -87,6 +91,117 @@ static inline void os_get_tmpdir(char *path, int len) GetTempPath(len, path); } +typedef DWORD_PTR os_cpu_mask_t; + +static inline int gettid(void) +{ + return GetCurrentThreadId(); +} + +static inline int pid_to_winpid(int pid) +{ + int winpid = 0; + DWORD outbytes = 0; + DWORD *ids = NULL; + size_t allocsize; + + allocsize = sizeof(DWORD) * 1024; + + do { + if (allocsize == outbytes) + allocsize *= 2; + + ids = realloc(ids, allocsize); + EnumProcesses(ids, allocsize, &outbytes); + } while (allocsize == outbytes); + + for (int i = 0; i < (outbytes/sizeof(DWORD)); i++) { + if (cygwin_winpid_to_pid(ids[i]) == pid) { + winpid = ids[i]; + break; + } + } + + free(ids); + return winpid; +} + +HANDLE WINAPI OpenThread( + DWORD dwDesiredAccess, + BOOL bInheritHandle, + DWORD dwThreadId); + +DWORD WINAPI GetProcessIdOfThread(HANDLE Thread); + +static inline int fio_setaffinity(int pid, os_cpu_mask_t cpumask) +{ + HANDLE h; + BOOL bSuccess; + int winpid; + + h = OpenThread(THREAD_QUERY_INFORMATION | THREAD_SET_INFORMATION, TRUE, pid); + if (h != NULL) { + bSuccess = SetThreadAffinityMask(h, cpumask); + } else { + // then we might have a process id instead of a thread id + winpid = pid_to_winpid(pid); + h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, TRUE, winpid); + if (h == NULL) + return -1; + + bSuccess = SetProcessAffinityMask(h, cpumask); + } + + CloseHandle(h); + + return (bSuccess)? 0 : -1; +} + +static inline void fio_getaffinity(int pid, os_cpu_mask_t *mask) +{ + os_cpu_mask_t systemMask; + int winpid; + + HANDLE h = OpenThread(THREAD_QUERY_INFORMATION, TRUE, pid); + if (h != NULL) + winpid = GetProcessIdOfThread(h); + else + winpid = pid_to_winpid(pid); + + h = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, winpid); + + if (h != NULL) { + GetProcessAffinityMask(h, mask, &systemMask); + CloseHandle(h); + } else { + fprintf(stderr, "fio_getaffinity failed: failed to get handle for pid %d\n", pid); + } + +} + +static inline void fio_cpu_clear(os_cpu_mask_t *mask, int cpu) +{ + *mask ^= 1 << (cpu-1); +} + +static inline void fio_cpu_set(os_cpu_mask_t *mask, int cpu) +{ + *mask |= 1 << (cpu-1); +} + +static inline int fio_cpuset_init(os_cpu_mask_t *mask) +{ + *mask = 0; + return 0; +} + +static inline int fio_cpuset_exit(os_cpu_mask_t *mask) +{ + return 0; +} + +#define FIO_MAX_CPUS MAXIMUM_PROCESSORS + #ifdef MADV_FREE #define FIO_MADV_FREE MADV_FREE #endif diff --git a/os/windows/install.wxs b/os/windows/install.wxs index 888cb57..a6e1642 100755 --- a/os/windows/install.wxs +++ b/os/windows/install.wxs @@ -2,7 +2,7 @@ <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <?define VersionMajor = 1?> -<?define VersionMinor = 55?> +<?define VersionMinor = 57?> <?define VersionBuild = 0?> <Product Id="*" diff --git a/os/windows/version.h b/os/windows/version.h index e9971c8..0e6cea9 100644 --- a/os/windows/version.h +++ b/os/windows/version.h @@ -1,4 +1,4 @@ #define FIO_VERSION_MAJOR 1 -#define FIO_VERSION_MINOR 55 +#define FIO_VERSION_MINOR 57 #define FIO_VERSION_BUILD 0 -#define FIO_VERSION_STRING "1.55" +#define FIO_VERSION_STRING "1.57" -- 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