Add CPU affinity support to Windows
[fio.git] / os / os-windows.h
CommitLineData
03e20d68
BC
1#ifndef FIO_OS_WINDOWS_H\r
2#define FIO_OS_WINDOWS_H\r
3\r
03e20d68
BC
4#include <sys/types.h>\r
5#include <errno.h>\r
ecc314ba 6#include <windows.h>\r
0f7ac781 7#include <psapi.h>\r
03e20d68 8\r
ecc314ba
BC
9#include "../smalloc.h"\r
10#include "../file.h"\r
11#include "../log.h"\r
03e20d68
BC
12\r
13#define FIO_HAVE_ODIRECT\r
0f7ac781 14#define FIO_HAVE_CPU_AFFINITY\r
03e20d68 15#define FIO_HAVE_CHARDEV_SIZE\r
03e20d68
BC
16#define FIO_HAVE_FALLOCATE\r
17#define FIO_HAVE_FDATASYNC\r
18#define FIO_HAVE_WINDOWSAIO\r
19\r
0f7ac781
BC
20#define FIO_USE_GENERIC_RAND\r
21\r
03e20d68
BC
22#define OS_MAP_ANON MAP_ANON\r
23\r
ecc314ba 24#define OS_CLOCK CLOCK_REALTIME\r
03e20d68 25\r
58483fa4
JA
26#define FIO_PREFERRED_ENGINE "windowsaio"\r
27\r
ecc314ba 28typedef off_t off64_t;\r
03e20d68
BC
29\r
30typedef struct {\r
31 LARGE_INTEGER Length;\r
32} GET_LENGTH_INFORMATION;\r
33\r
34#define IOCTL_DISK_GET_LENGTH_INFO 0x7405C\r
35\r
0f7ac781
BC
36pid_t cygwin_winpid_to_pid(int winpid);\r
37\r
ecc314ba 38static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes)\r
03e20d68
BC
39{\r
40 int rc = 0;\r
ecc314ba
BC
41 HANDLE hFile;\r
42\r
43 if (f->hFile == NULL) {\r
9b836561
BC
44 hFile = CreateFile(f->file_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,\r
45 NULL, OPEN_EXISTING, 0, NULL);\r
ecc314ba
BC
46 } else {\r
47 hFile = f->hFile;\r
03e20d68
BC
48 }\r
49\r
ecc314ba
BC
50 GET_LENGTH_INFORMATION info;\r
51 DWORD outBytes;\r
52 LARGE_INTEGER size;\r
53 size.QuadPart = 0;\r
54 if (DeviceIoControl(hFile, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &info, sizeof(info), &outBytes, NULL))\r
55 *bytes = info.Length.QuadPart;\r
56 else\r
57 rc = EIO;\r
ecc314ba
BC
58\r
59 /* If we were passed a POSIX fd,\r
60 * close the HANDLE we created via CreateFile */\r
61 if (hFile != INVALID_HANDLE_VALUE && f->hFile == NULL)\r
62 CloseHandle(hFile);\r
63\r
64 return rc;\r
03e20d68
BC
65}\r
66\r
ecc314ba 67static inline int chardev_size(struct fio_file *f, unsigned long long *bytes)\r
03e20d68 68{\r
ecc314ba 69 return blockdev_size(f, bytes);\r
03e20d68
BC
70}\r
71\r
ecc314ba
BC
72static inline int blockdev_invalidate_cache(struct fio_file *f)\r
73{\r
e4db9fec
BC
74 /* There's no way to invalidate the cache in Windows\r
75 * so just pretend to succeed */\r
ecc314ba 76 return 0;\r
03e20d68
BC
77}\r
78\r
79static inline unsigned long long os_phys_mem(void)\r
80{\r
81 SYSTEM_INFO sysInfo;\r
82 unsigned long addr;\r
83 GetSystemInfo(&sysInfo);\r
84 addr = (unsigned long)sysInfo.lpMaximumApplicationAddress;\r
85 return addr;\r
86}\r
87\r
88static inline void os_get_tmpdir(char *path, int len)\r
89{\r
90 GetTempPath(len, path);\r
91}\r
92\r
0f7ac781
BC
93typedef DWORD_PTR os_cpu_mask_t;\r
94\r
95static inline int pid_to_winpid(int pid)\r
96{\r
97 int winpid = 0;\r
98 DWORD outbytes = 0;\r
99 DWORD *ids = NULL;\r
100 size_t allocsize;\r
101 \r
102 allocsize = sizeof(DWORD) * 1024;\r
103 \r
104 do {\r
105 if (allocsize == outbytes)\r
106 allocsize *= 2;\r
107\r
108 ids = realloc(ids, allocsize);\r
109 EnumProcesses(ids, allocsize, &outbytes);\r
110 } while (allocsize == outbytes);\r
111 \r
112 for (int i = 0; i < (outbytes/sizeof(DWORD)); i++) {\r
113 if (cygwin_winpid_to_pid(ids[i]) == pid) {\r
114 winpid = ids[i];\r
115 break;\r
116 }\r
117 }\r
118 \r
119 free(ids);\r
120 return winpid;\r
121}\r
122\r
123static inline int fio_setaffinity(int pid, os_cpu_mask_t cpumask)\r
124{\r
125 int winpid = pid_to_winpid(pid);\r
126 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, TRUE, winpid);\r
127 if (h == NULL)\r
128 return -1;\r
129 \r
130 BOOL bSuccess = SetProcessAffinityMask(h, cpumask);\r
131 CloseHandle(h);\r
132 return (bSuccess)? 0 : -1;\r
133}\r
134\r
135static inline void fio_getaffinity(int pid, os_cpu_mask_t *mask)\r
136{\r
137 os_cpu_mask_t systemMask;\r
138 int winpid = pid_to_winpid(pid);\r
139 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, winpid);\r
140 if (h == NULL)\r
141 {\r
142 printf("OpenProcess failed!\n");\r
143 return;\r
144 }\r
145 \r
146 GetProcessAffinityMask(h, mask, &systemMask);\r
147 CloseHandle(h);\r
148}\r
149\r
150static inline void fio_cpu_clear(os_cpu_mask_t *mask, int cpu)\r
151{\r
152 *mask ^= 1 << (cpu-1);\r
153}\r
154\r
155static inline void fio_cpu_set(os_cpu_mask_t *mask, int cpu)\r
156{\r
157 *mask |= 1 << (cpu-1);\r
158}\r
159\r
160static inline int fio_cpuset_init(os_cpu_mask_t *mask)\r
161{\r
162 *mask = 0;\r
163 return 0;\r
164}\r
165\r
166static inline int fio_cpuset_exit(os_cpu_mask_t *mask)\r
167{\r
168 return 0;\r
169}\r
170\r
171#define FIO_MAX_CPUS MAXIMUM_PROCESSORS\r
172\r
03e20d68
BC
173#ifdef MADV_FREE\r
174#define FIO_MADV_FREE MADV_FREE\r
175#endif\r
176\r
03e20d68 177#endif /* FIO_OS_WINDOWS_H */\r