1 #ifndef FIO_OS_H 2 #define FIO_OS_H 3 4 #include <sys/types.h> 5 #include <sys/socket.h> 6 #include <fcntl.h> 7 #include <pthread.h> 8 #include <unistd.h> 9 #include <stdlib.h> 10 11 #include "../arch/arch.h" 12 13 enum { 14 os_linux = 1, 15 os_aix, 16 os_freebsd, 17 os_hpux, 18 os_mac, 19 os_netbsd, 20 os_openbsd, 21 os_solaris, 22 os_windows, 23 os_android, 24 os_dragonfly, 25 26 os_nr, 27 }; 28 29 #if defined(__ANDROID__) 30 #include "os-android.h" 31 #elif defined(__linux__) 32 #include "os-linux.h" 33 #elif defined(__FreeBSD__) 34 #include "os-freebsd.h" 35 #elif defined(__OpenBSD__) 36 #include "os-openbsd.h" 37 #elif defined(__NetBSD__) 38 #include "os-netbsd.h" 39 #elif defined(__sun__) 40 #include "os-solaris.h" 41 #elif defined(__APPLE__) 42 #include "os-mac.h" 43 #elif defined(_AIX) 44 #include "os-aix.h" 45 #elif defined(__hpux) 46 #include "os-hpux.h" 47 #elif defined(WIN32) 48 #include "os-windows.h" 49 #elif defined (__DragonFly__) 50 #include "os-dragonfly.h" 51 #else 52 #error "unsupported os" 53 #endif 54 55 #ifdef CONFIG_POSIXAIO 56 #include <aio.h> 57 #ifndef FIO_OS_HAVE_AIOCB_TYPEDEF 58 typedef struct aiocb os_aiocb_t; 59 #endif 60 #endif 61 62 #ifdef FIO_HAVE_SGIO 63 #include <linux/fs.h> 64 #include <scsi/sg.h> 65 #endif 66 67 #ifndef CONFIG_STRSEP 68 #include "../lib/strsep.h" 69 #endif 70 71 #ifdef MSG_DONTWAIT 72 #define OS_MSG_DONTWAIT MSG_DONTWAIT 73 #endif 74 75 #ifndef POSIX_FADV_DONTNEED 76 #define POSIX_FADV_DONTNEED (0) 77 #define POSIX_FADV_SEQUENTIAL (0) 78 #define POSIX_FADV_RANDOM (0) 79 #endif 80 81 #ifndef FIO_HAVE_CPU_AFFINITY 82 #define fio_setaffinity(pid, mask) (0) 83 #define fio_getaffinity(pid, mask) do { } while (0) 84 #define fio_cpu_clear(mask, cpu) do { } while (0) 85 #define fio_cpuset_exit(mask) (-1) 86 #define fio_cpus_split(mask, cpu) (0) 87 typedef unsigned long os_cpu_mask_t; 88 #else 89 extern int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu); 90 #endif 91 92 #ifndef FIO_HAVE_IOPRIO 93 #define ioprio_set(which, who, prioclass, prio) (0) 94 #endif 95 96 #ifndef FIO_HAVE_ODIRECT 97 #define OS_O_DIRECT 0 98 #else 99 #define OS_O_DIRECT O_DIRECT 100 #endif 101 102 #ifdef OS_O_ATOMIC 103 #define FIO_O_ATOMIC OS_O_ATOMIC 104 #else 105 #define FIO_O_ATOMIC 0 106 #endif 107 108 #ifndef FIO_HAVE_HUGETLB 109 #define SHM_HUGETLB 0 110 #define MAP_HUGETLB 0 111 #ifndef FIO_HUGE_PAGE 112 #define FIO_HUGE_PAGE 0 113 #endif 114 #else 115 #ifndef FIO_HUGE_PAGE 116 #define FIO_HUGE_PAGE 4194304 117 #endif 118 #endif 119 120 #ifndef FIO_HAVE_MMAP_HUGE 121 #define MAP_HUGETLB 0 122 #endif 123 124 #ifndef FIO_O_NOATIME 125 #define FIO_O_NOATIME 0 126 #endif 127 128 #ifndef OS_RAND_MAX 129 #define OS_RAND_MAX RAND_MAX 130 #endif 131 132 #ifndef FIO_HAVE_RAWBIND 133 #define fio_lookup_raw(dev, majdev, mindev) 1 134 #endif 135 136 #ifndef FIO_PREFERRED_ENGINE 137 #define FIO_PREFERRED_ENGINE "sync" 138 #endif 139 140 #ifndef FIO_OS_PATH_SEPARATOR 141 #define FIO_OS_PATH_SEPARATOR "/" 142 #endif 143 144 #ifndef FIO_PREFERRED_CLOCK_SOURCE 145 #ifdef CONFIG_CLOCK_GETTIME 146 #define FIO_PREFERRED_CLOCK_SOURCE CS_CGETTIME 147 #else 148 #define FIO_PREFERRED_CLOCK_SOURCE CS_GTOD 149 #endif 150 #endif 151 152 #ifndef FIO_MAX_JOBS 153 #define FIO_MAX_JOBS 2048 154 #endif 155 156 #ifndef CONFIG_SOCKLEN_T 157 typedef unsigned int socklen_t; 158 #endif 159 160 #ifndef FIO_OS_HAS_CTIME_R 161 #define os_ctime_r(x, y, z) (void) ctime_r((x), (y)) 162 #endif 163 164 #ifdef FIO_USE_GENERIC_SWAP 165 static inline uint16_t fio_swap16(uint16_t val) 166 { 167 return (val << 8) | (val >> 8); 168 } 169 170 static inline uint32_t fio_swap32(uint32_t val) 171 { 172 val = ((val & 0xff00ff00UL) >> 8) | ((val & 0x00ff00ffUL) << 8); 173 174 return (val >> 16) | (val << 16); 175 } 176 177 static inline uint64_t fio_swap64(uint64_t val) 178 { 179 val = ((val & 0xff00ff00ff00ff00ULL) >> 8) | 180 ((val & 0x00ff00ff00ff00ffULL) << 8); 181 val = ((val & 0xffff0000ffff0000ULL) >> 16) | 182 ((val & 0x0000ffff0000ffffULL) << 16); 183 184 return (val >> 32) | (val << 32); 185 } 186 #endif 187 188 #ifndef FIO_HAVE_BYTEORDER_FUNCS 189 #ifdef CONFIG_LITTLE_ENDIAN 190 #define __le16_to_cpu(x) (x) 191 #define __le32_to_cpu(x) (x) 192 #define __le64_to_cpu(x) (x) 193 #define __cpu_to_le16(x) (x) 194 #define __cpu_to_le32(x) (x) 195 #define __cpu_to_le64(x) (x) 196 #else 197 #define __le16_to_cpu(x) fio_swap16(x) 198 #define __le32_to_cpu(x) fio_swap32(x) 199 #define __le64_to_cpu(x) fio_swap64(x) 200 #define __cpu_to_le16(x) fio_swap16(x) 201 #define __cpu_to_le32(x) fio_swap32(x) 202 #define __cpu_to_le64(x) fio_swap64(x) 203 #endif 204 #endif /* FIO_HAVE_BYTEORDER_FUNCS */ 205 206 #ifdef FIO_INTERNAL 207 #define le16_to_cpu(val) ({ \ 208 typecheck(uint16_t, val); \ 209 __le16_to_cpu(val); \ 210 }) 211 #define le32_to_cpu(val) ({ \ 212 typecheck(uint32_t, val); \ 213 __le32_to_cpu(val); \ 214 }) 215 #define le64_to_cpu(val) ({ \ 216 typecheck(uint64_t, val); \ 217 __le64_to_cpu(val); \ 218 }) 219 #endif 220 221 #define cpu_to_le16(val) ({ \ 222 typecheck(uint16_t, val); \ 223 __cpu_to_le16(val); \ 224 }) 225 #define cpu_to_le32(val) ({ \ 226 typecheck(uint32_t, val); \ 227 __cpu_to_le32(val); \ 228 }) 229 #define cpu_to_le64(val) ({ \ 230 typecheck(uint64_t, val); \ 231 __cpu_to_le64(val); \ 232 }) 233 234 #ifndef FIO_HAVE_BLKTRACE 235 static inline int is_blktrace(const char *fname, int *need_swap) 236 { 237 return 0; 238 } 239 struct thread_data; 240 static inline int load_blktrace(struct thread_data *td, const char *fname, 241 int need_swap) 242 { 243 return 1; 244 } 245 #endif 246 247 #define FIO_DEF_CL_SIZE 128 248 249 static inline int os_cache_line_size(void) 250 { 251 #ifdef FIO_HAVE_CL_SIZE 252 int ret = arch_cache_line_size(); 253 254 if (ret <= 0) 255 return FIO_DEF_CL_SIZE; 256 257 return ret; 258 #else 259 return FIO_DEF_CL_SIZE; 260 #endif 261 } 262 263 #ifdef FIO_USE_GENERIC_BDEV_SIZE 264 static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) 265 { 266 off_t end; 267 268 *bytes = 0; 269 270 end = lseek(f->fd, 0, SEEK_END); 271 if (end < 0) 272 return errno; 273 274 *bytes = end; 275 return 0; 276 } 277 #endif 278 279 #ifdef FIO_USE_GENERIC_RAND 280 typedef unsigned int os_random_state_t; 281 282 static inline void os_random_seed(unsigned long seed, os_random_state_t *rs) 283 { 284 srand(seed); 285 } 286 287 static inline long os_random_long(os_random_state_t *rs) 288 { 289 long val; 290 291 val = rand_r(rs); 292 return val; 293 } 294 #endif 295 296 #ifdef FIO_USE_GENERIC_INIT_RANDOM_STATE 297 extern void td_fill_rand_seeds(struct thread_data *td); 298 /* 299 * Initialize the various random states we need (random io, block size ranges, 300 * read/write mix, etc). 301 */ 302 static inline int init_random_state(struct thread_data *td, unsigned long *rand_seeds, int size) 303 { 304 int fd; 305 306 fd = open("/dev/urandom", O_RDONLY); 307 if (fd == -1) { 308 return 1; 309 } 310 311 if (read(fd, rand_seeds, size) < size) { 312 close(fd); 313 return 1; 314 } 315 316 close(fd); 317 td_fill_rand_seeds(td); 318 return 0; 319 } 320 #endif 321 322 #ifndef FIO_HAVE_FS_STAT 323 static inline unsigned long long get_fs_size(const char *path) 324 { 325 return 0; 326 } 327 #endif 328 329 #ifndef FIO_HAVE_CPU_ONLINE_SYSCONF 330 static inline unsigned int cpus_online(void) 331 { 332 return sysconf(_SC_NPROCESSORS_ONLN); 333 } 334 #endif 335 336 #ifndef CPU_COUNT 337 #ifdef FIO_HAVE_CPU_AFFINITY 338 static inline int CPU_COUNT(os_cpu_mask_t *mask) 339 { 340 int max_cpus = cpus_online(); 341 int nr_cpus, i; 342 343 for (i = 0, nr_cpus = 0; i < max_cpus; i++) 344 if (fio_cpu_isset(mask, i)) 345 nr_cpus++; 346 347 return nr_cpus; 348 } 349 #endif 350 #endif 351 352 #ifndef FIO_HAVE_GETTID 353 static inline int gettid(void) 354 { 355 return getpid(); 356 } 357 #endif 358 359 #endif 360