X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=os%2Fos-windows.h;h=06fe4335beb7bda4095dd3304c8deab454ecfb38;hp=8812cfa2e0d76943d398acc11e5b67787a7d9b50;hb=93bcfd20e37cef8cec350fe06d3a086724c9f257;hpb=16de1bf91ca80e62ce257a24cae471fab140bbe0 diff --git a/os/os-windows.h b/os/os-windows.h index 8812cfa2..06fe4335 100644 --- a/os/os-windows.h +++ b/os/os-windows.h @@ -1,220 +1,252 @@ -#ifndef FIO_OS_WINDOWS_H -#define FIO_OS_WINDOWS_H - -#define FIO_OS os_windows - -#include -#include -#include -#include -#include - -#include "../smalloc.h" -#include "../file.h" -#include "../log.h" - -#define FIO_HAVE_ODIRECT -#define FIO_HAVE_CPU_AFFINITY -#define FIO_HAVE_CHARDEV_SIZE -#define FIO_HAVE_FALLOCATE -#define FIO_HAVE_FDATASYNC -#define FIO_HAVE_WINDOWSAIO -#define FIO_HAVE_GETTID - -#define FIO_OS_HAVE_SOCKLEN_T -typedef int fio_socklen_t; - -#define FIO_USE_GENERIC_RAND - -#define OS_MAP_ANON MAP_ANON - -#define OS_CLOCK CLOCK_REALTIME - -#define FIO_PREFERRED_ENGINE "windowsaio" - -#define FIO_LITTLE_ENDIAN -#define fio_swap16(x) _byteswap_ushort(x) -#define fio_swap32(x) _byteswap_ulong(x) -#define fio_swap64(x) _byteswap_uint64(x) - -typedef off_t off64_t; - -typedef struct { - LARGE_INTEGER Length; -} GET_LENGTH_INFORMATION; - -#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; - HANDLE hFile; - - if (f->hFile == NULL) { - hFile = CreateFile(f->file_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, NULL); - } else { - hFile = f->hFile; - } - - GET_LENGTH_INFORMATION info; - DWORD outBytes; - LARGE_INTEGER size; - size.QuadPart = 0; - if (DeviceIoControl(hFile, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &info, sizeof(info), &outBytes, NULL)) - *bytes = info.Length.QuadPart; - else - rc = EIO; - - /* If we were passed a POSIX fd, - * close the HANDLE we created via CreateFile */ - if (hFile != INVALID_HANDLE_VALUE && f->hFile == NULL) - CloseHandle(hFile); - - return rc; -} - -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) -{ - /* There's no way to invalidate the cache in Windows - * so just pretend to succeed */ - return 0; -} - -static inline unsigned long long os_phys_mem(void) -{ - SYSTEM_INFO sysInfo; - unsigned long addr; - GetSystemInfo(&sysInfo); - addr = (unsigned long)sysInfo.lpMaximumApplicationAddress; - return addr; -} - -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 - -#endif /* FIO_OS_WINDOWS_H */ +#ifndef FIO_OS_WINDOWS_H +#define FIO_OS_WINDOWS_H + +#define FIO_OS os_windows + +#include +#include +#include +#include +#include +#include +#include + +#include "../smalloc.h" +#include "../file.h" +#include "../log.h" + +#define FIO_HAVE_ODIRECT +#define FIO_HAVE_CPU_AFFINITY +#define FIO_HAVE_CHARDEV_SIZE +#define FIO_HAVE_FDATASYNC +#define FIO_HAVE_WINDOWSAIO +#define FIO_HAVE_GETTID +#define FIO_HAVE_CLOCK_MONOTONIC +#define FIO_USE_GENERIC_RAND + +#define FIO_PREFERRED_ENGINE "windowsaio" +#define FIO_PREFERRED_CLOCK_SOURCE CS_CGETTIME +#define FIO_OS_PATH_SEPARATOR "\\" + +#define FIO_MAX_CPUS MAXIMUM_PROCESSORS + +#define FIO_OS_HAVE_SOCKLEN_T +typedef int fio_socklen_t; + +#define OS_MAP_ANON MAP_ANON + +#define FIO_LITTLE_ENDIAN +#define fio_swap16(x) _byteswap_ushort(x) +#define fio_swap32(x) _byteswap_ulong(x) +#define fio_swap64(x) _byteswap_uint64(x) + +typedef off_t off64_t; +typedef int clockid_t; + +typedef DWORD_PTR os_cpu_mask_t; + +#define CLOCK_REALTIME 1 +#define CLOCK_MONOTONIC 2 + +#define _SC_PAGESIZE 0x1 +#define _SC_NPROCESSORS_ONLN 0x2 +#define _SC_PHYS_PAGES 0x4 + +#define SA_RESTART 0 +#define SIGPIPE 0 + +/* + * Windows doesn't have O_DIRECT or O_SYNC, so define them + * here so we can reject them at runtime when using the _open + * interface (windowsaio uses CreateFile) + */ +#define O_DIRECT 0x1000000 +#define O_SYNC 0x2000000 + +/* Windows doesn't support madvise, so any values will work */ +#define POSIX_MADV_DONTNEED 0 +#define POSIX_MADV_SEQUENTIAL 0 +#define POSIX_MADV_RANDOM 0 + +#define F_SETFL 0x1 +#define F_GETFL 0x2 +#define O_NONBLOCK FIONBIO + +/* Winsock doesn't support MSG_WAIT */ +#define OS_MSG_DONTWAIT 0 + +#define POLLOUT 1 +#define POLLIN 2 +#define POLLERR 0 +#define POLLHUP 1 + +#define SIGCONT 0 + +typedef int sigset_t; +typedef int siginfo_t; + +struct sigaction +{ + void (*sa_handler)(int); + sigset_t sa_mask; + int sa_flags; + void* (*sa_sigaction)(int, siginfo_t *, void*); +}; + +char *strsep(char **stringp, const char *delim); +long sysconf(int name); + +int kill(pid_t pid, int sig); +pid_t setsid(void); +int setgid(gid_t gid); +int setuid(uid_t uid); +int nice(int incr); +int sigaction(int sig, const struct sigaction *act, + struct sigaction *oact); +int fsync(int fildes); +int fork(void); +int fcntl(int fildes, int cmd, ...); +int fdatasync(int fildes); +int lstat(const char * path, struct stat * buf); +uid_t geteuid(void); +int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); +ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset); +ssize_t pwrite(int fildes, const void *buf, size_t nbyte, + off_t offset); +extern void td_fill_rand_seeds(struct thread_data *); + +static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) +{ + int rc = 0; + HANDLE hFile; + + if (f->hFile == NULL) { + hFile = CreateFile(f->file_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + } else { + hFile = f->hFile; + } + + GET_LENGTH_INFORMATION info; + DWORD outBytes; + LARGE_INTEGER size; + size.QuadPart = 0; + if (DeviceIoControl(hFile, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &info, sizeof(info), &outBytes, NULL)) + *bytes = info.Length.QuadPart; + else + rc = EIO; + + /* If we were passed a POSIX fd, + * close the HANDLE we created via CreateFile */ + if (hFile != INVALID_HANDLE_VALUE && f->hFile == NULL) + CloseHandle(hFile); + + return rc; +} + +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) +{ + /* There's no way to invalidate the cache in Windows + * so just pretend to succeed */ + return 0; +} + +static inline unsigned long long os_phys_mem(void) +{ + SYSTEM_INFO sysInfo; + uintptr_t addr; + + GetSystemInfo(&sysInfo); + addr = (uintptr_t)sysInfo.lpMaximumApplicationAddress; + return (unsigned long long)addr; +} + +static inline void os_get_tmpdir(char *path, int len) +{ + GetTempPath(len, path); +} + +static inline int gettid(void) +{ + return GetCurrentThreadId(); +} + +static inline int fio_setaffinity(int pid, os_cpu_mask_t cpumask) +{ + HANDLE h; + BOOL bSuccess = FALSE; + + h = OpenThread(THREAD_QUERY_INFORMATION | THREAD_SET_INFORMATION, TRUE, pid); + if (h != NULL) { + bSuccess = SetThreadAffinityMask(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; + + HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, pid); + + if (h != NULL) { + GetProcessAffinityMask(h, mask, &systemMask); + CloseHandle(h); + } else { + log_err("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; +} + +static inline int init_random_state(struct thread_data *td, unsigned long *rand_seeds, int size) +{ + HCRYPTPROV hCryptProv; + + if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + errno = GetLastError(); + log_err("CryptAcquireContext() failed: error %d\n", errno); + return 1; + } + + if (!CryptGenRandom(hCryptProv, size, (BYTE*)rand_seeds)) { + errno = GetLastError(); + log_err("CryptGenRandom() failed, error %d\n", errno); + CryptReleaseContext(hCryptProv, 0); + return 1; + } + + CryptReleaseContext(hCryptProv, 0); + td_fill_rand_seeds(td); + return 0; +} + + +#endif /* FIO_OS_WINDOWS_H */