More endianness for platforms
[fio.git] / os / os-windows.h
1 #ifndef FIO_OS_WINDOWS_H\r
2 #define FIO_OS_WINDOWS_H\r
3 \r
4 #include <sys/types.h>\r
5 #include <errno.h>\r
6 #include <windows.h>\r
7 #include <psapi.h>\r
8 #include <stdlib.h>\r
9 \r
10 #include "../smalloc.h"\r
11 #include "../file.h"\r
12 #include "../log.h"\r
13 \r
14 #define FIO_HAVE_ODIRECT\r
15 #define FIO_HAVE_CPU_AFFINITY\r
16 #define FIO_HAVE_CHARDEV_SIZE\r
17 #define FIO_HAVE_FALLOCATE\r
18 #define FIO_HAVE_FDATASYNC\r
19 #define FIO_HAVE_WINDOWSAIO\r
20 #define FIO_HAVE_GETTID\r
21 \r
22 #define FIO_USE_GENERIC_RAND\r
23 \r
24 #define OS_MAP_ANON             MAP_ANON\r
25 \r
26 #define OS_CLOCK CLOCK_REALTIME\r
27 \r
28 #define FIO_PREFERRED_ENGINE    "windowsaio"\r
29 \r
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
35 typedef off_t off64_t;\r
36 \r
37 typedef 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
43 pid_t cygwin_winpid_to_pid(int winpid);\r
44 \r
45 static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes)\r
46 {\r
47         int rc = 0;\r
48         HANDLE hFile;\r
49 \r
50         if (f->hFile == NULL) {\r
51                 hFile = CreateFile(f->file_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,\r
52                                 NULL, OPEN_EXISTING, 0, NULL);\r
53         } else {\r
54                 hFile = f->hFile;\r
55         }\r
56 \r
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
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
72 }\r
73 \r
74 static inline int chardev_size(struct fio_file *f, unsigned long long *bytes)\r
75 {\r
76         return blockdev_size(f, bytes);\r
77 }\r
78 \r
79 static inline int blockdev_invalidate_cache(struct fio_file *f)\r
80 {\r
81         /* There's no way to invalidate the cache in Windows\r
82          * so just pretend to succeed */\r
83         return 0;\r
84 }\r
85 \r
86 static 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
95 static inline void os_get_tmpdir(char *path, int len)\r
96 {\r
97         GetTempPath(len, path);\r
98 }\r
99 \r
100 typedef DWORD_PTR os_cpu_mask_t;\r
101 \r
102 static inline int gettid(void)\r
103 {\r
104         return GetCurrentThreadId();\r
105 }\r
106 \r
107 static 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
135 HANDLE WINAPI OpenThread(\r
136     DWORD dwDesiredAccess,\r
137     BOOL bInheritHandle,\r
138     DWORD dwThreadId);\r
139     \r
140 DWORD WINAPI GetProcessIdOfThread(HANDLE Thread);\r
141 \r
142 static inline int fio_setaffinity(int pid, os_cpu_mask_t cpumask)\r
143 {\r
144         HANDLE h;\r
145         BOOL bSuccess;\r
146         int winpid;\r
147         \r
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
161         CloseHandle(h);\r
162 \r
163         return (bSuccess)? 0 : -1;\r
164 }\r
165 \r
166 static inline void fio_getaffinity(int pid, os_cpu_mask_t *mask)\r
167 {\r
168         os_cpu_mask_t systemMask;\r
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
186 }\r
187 \r
188 static 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
193 static 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
198 static 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
204 static 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
211 #ifdef MADV_FREE\r
212 #define FIO_MADV_FREE   MADV_FREE\r
213 #endif\r
214 \r
215 #endif /* FIO_OS_WINDOWS_H */\r