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