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