Fio 1.99.1
[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
232f9b73 8#include <stdlib.h>\r
03e20d68 9\r
ecc314ba
BC
10#include "../smalloc.h"\r
11#include "../file.h"\r
12#include "../log.h"\r
03e20d68
BC
13\r
14#define FIO_HAVE_ODIRECT\r
0f7ac781 15#define FIO_HAVE_CPU_AFFINITY\r
03e20d68 16#define FIO_HAVE_CHARDEV_SIZE\r
03e20d68
BC
17#define FIO_HAVE_FALLOCATE\r
18#define FIO_HAVE_FDATASYNC\r
19#define FIO_HAVE_WINDOWSAIO\r
1332757c 20#define FIO_HAVE_GETTID\r
03e20d68 21\r
0f7ac781
BC
22#define FIO_USE_GENERIC_RAND\r
23\r
03e20d68
BC
24#define OS_MAP_ANON MAP_ANON\r
25\r
ecc314ba 26#define OS_CLOCK CLOCK_REALTIME\r
03e20d68 27\r
58483fa4
JA
28#define FIO_PREFERRED_ENGINE "windowsaio"\r
29\r
232f9b73
JA
30#define FIO_LITTLE_ENDIAN\r
31#define fio_swap16(x) _byteswap_ushort(x)\r
32#define fio_swap32(x) _byteswap_ulong(x)\r
33#define fio_swap64(x) _byteswap_uint64(x)\r
34\r
ecc314ba 35typedef off_t off64_t;\r
03e20d68
BC
36\r
37typedef struct {\r
38 LARGE_INTEGER Length;\r
39} GET_LENGTH_INFORMATION;\r
40\r
41#define IOCTL_DISK_GET_LENGTH_INFO 0x7405C\r
42\r
0f7ac781
BC
43pid_t cygwin_winpid_to_pid(int winpid);\r
44\r
ecc314ba 45static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes)\r
03e20d68
BC
46{\r
47 int rc = 0;\r
ecc314ba
BC
48 HANDLE hFile;\r
49\r
50 if (f->hFile == NULL) {\r
9b836561
BC
51 hFile = CreateFile(f->file_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,\r
52 NULL, OPEN_EXISTING, 0, NULL);\r
ecc314ba
BC
53 } else {\r
54 hFile = f->hFile;\r
03e20d68
BC
55 }\r
56\r
ecc314ba
BC
57 GET_LENGTH_INFORMATION info;\r
58 DWORD outBytes;\r
59 LARGE_INTEGER size;\r
60 size.QuadPart = 0;\r
61 if (DeviceIoControl(hFile, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &info, sizeof(info), &outBytes, NULL))\r
62 *bytes = info.Length.QuadPart;\r
63 else\r
64 rc = EIO;\r
ecc314ba
BC
65\r
66 /* If we were passed a POSIX fd,\r
67 * close the HANDLE we created via CreateFile */\r
68 if (hFile != INVALID_HANDLE_VALUE && f->hFile == NULL)\r
69 CloseHandle(hFile);\r
70\r
71 return rc;\r
03e20d68
BC
72}\r
73\r
ecc314ba 74static inline int chardev_size(struct fio_file *f, unsigned long long *bytes)\r
03e20d68 75{\r
ecc314ba 76 return blockdev_size(f, bytes);\r
03e20d68
BC
77}\r
78\r
ecc314ba
BC
79static inline int blockdev_invalidate_cache(struct fio_file *f)\r
80{\r
e4db9fec
BC
81 /* There's no way to invalidate the cache in Windows\r
82 * so just pretend to succeed */\r
ecc314ba 83 return 0;\r
03e20d68
BC
84}\r
85\r
86static inline unsigned long long os_phys_mem(void)\r
87{\r
88 SYSTEM_INFO sysInfo;\r
89 unsigned long addr;\r
90 GetSystemInfo(&sysInfo);\r
91 addr = (unsigned long)sysInfo.lpMaximumApplicationAddress;\r
92 return addr;\r
93}\r
94\r
95static inline void os_get_tmpdir(char *path, int len)\r
96{\r
97 GetTempPath(len, path);\r
98}\r
99\r
0f7ac781
BC
100typedef DWORD_PTR os_cpu_mask_t;\r
101\r
1332757c
BC
102static inline int gettid(void)\r
103{\r
104 return GetCurrentThreadId();\r
105}\r
106\r
0f7ac781
BC
107static inline int pid_to_winpid(int pid)\r
108{\r
109 int winpid = 0;\r
110 DWORD outbytes = 0;\r
111 DWORD *ids = NULL;\r
112 size_t allocsize;\r
113 \r
114 allocsize = sizeof(DWORD) * 1024;\r
115 \r
116 do {\r
117 if (allocsize == outbytes)\r
118 allocsize *= 2;\r
119\r
120 ids = realloc(ids, allocsize);\r
121 EnumProcesses(ids, allocsize, &outbytes);\r
122 } while (allocsize == outbytes);\r
123 \r
124 for (int i = 0; i < (outbytes/sizeof(DWORD)); i++) {\r
125 if (cygwin_winpid_to_pid(ids[i]) == pid) {\r
126 winpid = ids[i];\r
127 break;\r
128 }\r
129 }\r
130 \r
131 free(ids);\r
132 return winpid;\r
133}\r
134\r
1332757c
BC
135HANDLE WINAPI OpenThread(\r
136 DWORD dwDesiredAccess,\r
137 BOOL bInheritHandle,\r
138 DWORD dwThreadId);\r
139 \r
140DWORD WINAPI GetProcessIdOfThread(HANDLE Thread);\r
141\r
0f7ac781
BC
142static inline int fio_setaffinity(int pid, os_cpu_mask_t cpumask)\r
143{\r
1332757c
BC
144 HANDLE h;\r
145 BOOL bSuccess;\r
146 int winpid;\r
0f7ac781 147 \r
1332757c
BC
148 h = OpenThread(THREAD_QUERY_INFORMATION | THREAD_SET_INFORMATION, TRUE, pid);\r
149 if (h != NULL) {\r
150 bSuccess = SetThreadAffinityMask(h, cpumask);\r
151 } else {\r
152 // then we might have a process id instead of a thread id\r
153 winpid = pid_to_winpid(pid);\r
154 h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, TRUE, winpid);\r
155 if (h == NULL)\r
156 return -1;\r
157\r
158 bSuccess = SetProcessAffinityMask(h, cpumask);\r
159 }\r
160\r
0f7ac781 161 CloseHandle(h);\r
1332757c 162\r
0f7ac781
BC
163 return (bSuccess)? 0 : -1;\r
164}\r
165\r
166static inline void fio_getaffinity(int pid, os_cpu_mask_t *mask)\r
167{\r
168 os_cpu_mask_t systemMask;\r
1332757c
BC
169 int winpid;\r
170 \r
171 HANDLE h = OpenThread(THREAD_QUERY_INFORMATION, TRUE, pid);\r
172 if (h != NULL)\r
173 winpid = GetProcessIdOfThread(h);\r
174 else\r
175 winpid = pid_to_winpid(pid);\r
176 \r
177 h = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, winpid);\r
178\r
179 if (h != NULL) {\r
180 GetProcessAffinityMask(h, mask, &systemMask);\r
181 CloseHandle(h);\r
182 } else {\r
183 fprintf(stderr, "fio_getaffinity failed: failed to get handle for pid %d\n", pid);\r
184 }\r
185 \r
0f7ac781
BC
186}\r
187\r
188static inline void fio_cpu_clear(os_cpu_mask_t *mask, int cpu)\r
189{\r
190 *mask ^= 1 << (cpu-1);\r
191}\r
192\r
193static inline void fio_cpu_set(os_cpu_mask_t *mask, int cpu)\r
194{\r
195 *mask |= 1 << (cpu-1);\r
196}\r
197\r
198static inline int fio_cpuset_init(os_cpu_mask_t *mask)\r
199{\r
200 *mask = 0;\r
201 return 0;\r
202}\r
203\r
204static inline int fio_cpuset_exit(os_cpu_mask_t *mask)\r
205{\r
206 return 0;\r
207}\r
208\r
209#define FIO_MAX_CPUS MAXIMUM_PROCESSORS\r
210\r
03e20d68
BC
211#ifdef MADV_FREE\r
212#define FIO_MADV_FREE MADV_FREE\r
213#endif\r
214\r
03e20d68 215#endif /* FIO_OS_WINDOWS_H */\r