1 #ifndef FIO_OS_APPLE_H 2 #define FIO_OS_APPLE_H 3 4 #define FIO_OS os_mac 5 6 #include <errno.h> 7 #include <fcntl.h> 8 #include <sys/disk.h> 9 #include <sys/sysctl.h> 10 #include <sys/time.h> 11 #include <unistd.h> 12 #include <signal.h> 13 #include <mach/mach_init.h> 14 #include <machine/endian.h> 15 #include <libkern/OSByteOrder.h> 16 17 #include "../file.h" 18 19 #define FIO_USE_GENERIC_RAND 20 #define FIO_USE_GENERIC_INIT_RANDOM_STATE 21 #define FIO_HAVE_GETTID 22 #define FIO_HAVE_CHARDEV_SIZE 23 24 #define OS_MAP_ANON MAP_ANON 25 26 #define fio_swap16(x) OSSwapInt16(x) 27 #define fio_swap32(x) OSSwapInt32(x) 28 #define fio_swap64(x) OSSwapInt64(x) 29 30 /* 31 * OSX has a pitifully small shared memory segment by default, 32 * so default to a lower number of max jobs supported 33 */ 34 #define FIO_MAX_JOBS 128 35 36 typedef off_t off64_t; 37 38 /* OS X as of 10.6 doesn't have the timer_* functions. 39 * Emulate the functionality using setitimer and sigaction here 40 */ 41 42 #define MAX_TIMERS 64 43 44 typedef unsigned int clockid_t; 45 typedef unsigned int timer_t; 46 47 struct itimerspec { 48 struct timespec it_value; 49 struct timespec it_interval; 50 }; 51 52 static struct sigevent fio_timers[MAX_TIMERS]; 53 static unsigned int num_timers = 0; 54 55 static void sig_alrm(int signum) 56 { 57 union sigval sv; 58 59 for (int i = 0; i < num_timers; i++) { 60 if (fio_timers[i].sigev_notify_function == NULL) 61 continue; 62 63 if (fio_timers[i].sigev_notify == SIGEV_THREAD) 64 fio_timers[i].sigev_notify_function(sv); 65 else if (fio_timers[i].sigev_notify == SIGEV_SIGNAL) 66 kill(getpid(), fio_timers[i].sigev_signo); 67 } 68 } 69 70 static inline int timer_settime(timer_t timerid, int flags, 71 const struct itimerspec *value, 72 struct itimerspec *ovalue) 73 { 74 struct sigaction sa; 75 struct itimerval tv; 76 struct itimerval tv_out; 77 int rc; 78 79 tv.it_interval.tv_sec = value->it_interval.tv_sec; 80 tv.it_interval.tv_usec = value->it_interval.tv_nsec / 1000; 81 82 tv.it_value.tv_sec = value->it_value.tv_sec; 83 tv.it_value.tv_usec = value->it_value.tv_nsec / 1000; 84 85 sa.sa_handler = sig_alrm; 86 sigemptyset(&sa.sa_mask); 87 sa.sa_flags = 0; 88 89 rc = sigaction(SIGALRM, &sa, NULL); 90 91 if (!rc) 92 rc = setitimer(ITIMER_REAL, &tv, &tv_out); 93 94 if (!rc && ovalue != NULL) { 95 ovalue->it_interval.tv_sec = tv_out.it_interval.tv_sec; 96 ovalue->it_interval.tv_nsec = tv_out.it_interval.tv_usec * 1000; 97 ovalue->it_value.tv_sec = tv_out.it_value.tv_sec; 98 ovalue->it_value.tv_nsec = tv_out.it_value.tv_usec * 1000; 99 } 100 101 return rc; 102 } 103 104 static inline int timer_delete(timer_t timer) 105 { 106 return 0; 107 } 108 109 #define FIO_OS_DIRECTIO 110 static inline int fio_set_odirect(int fd) 111 { 112 if (fcntl(fd, F_NOCACHE, 1) == -1) 113 return errno; 114 return 0; 115 } 116 117 static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) 118 { 119 uint32_t block_size; 120 uint64_t block_count; 121 122 if (ioctl(f->fd, DKIOCGETBLOCKCOUNT, &block_count) == -1) 123 return errno; 124 if (ioctl(f->fd, DKIOCGETBLOCKSIZE, &block_size) == -1) 125 return errno; 126 127 *bytes = block_size; 128 *bytes *= block_count; 129 return 0; 130 } 131 132 static inline int chardev_size(struct fio_file *f, unsigned long long *bytes) 133 { 134 /* 135 * Could be a raw block device, this is better than just assuming 136 * we can't get the size at all. 137 */ 138 if (!blockdev_size(f, bytes)) 139 return 0; 140 141 *bytes = -1ULL; 142 return 0; 143 } 144 145 static inline int blockdev_invalidate_cache(struct fio_file *f) 146 { 147 return EINVAL; 148 } 149 150 static inline unsigned long long os_phys_mem(void) 151 { 152 int mib[2] = { CTL_HW, HW_PHYSMEM }; 153 unsigned long long mem; 154 size_t len = sizeof(mem); 155 156 sysctl(mib, 2, &mem, &len, NULL, 0); 157 return mem; 158 } 159 160 static inline int gettid(void) 161 { 162 return mach_thread_self(); 163 } 164 165 /* 166 * For some reason, there's no header definition for fdatasync(), even 167 * if it exists. 168 */ 169 extern int fdatasync(int fd); 170 171 #endif 172