os-mac.h revision 7e8ad197a8d219e2fc181c881143f11891e7d0d5
1#ifndef FIO_OS_APPLE_H 2#define FIO_OS_APPLE_H 3 4#include <errno.h> 5#include <fcntl.h> 6#include <sys/disk.h> 7#include <sys/sysctl.h> 8#include <sys/time.h> 9#include <unistd.h> 10#include <signal.h> 11 12#include "../file.h" 13 14#ifndef CLOCK_MONOTONIC 15#define CLOCK_MONOTONIC 1 16#endif 17 18#ifndef CLOCK_REALTIME 19#define CLOCK_REALTIME 1 20#endif 21 22#define FIO_HAVE_POSIXAIO 23#define FIO_HAVE_CLOCK_MONOTONIC 24#define FIO_USE_GENERIC_RAND 25 26#define OS_MAP_ANON MAP_ANON 27 28typedef off_t off64_t; 29 30/* OS X as of 10.6 doesn't have the timer_* functions. 31 * Emulate the functionality using setitimer and sigaction here 32 */ 33 34#define MAX_TIMERS 64 35 36typedef unsigned int clockid_t; 37typedef unsigned int timer_t; 38 39struct itimerspec { 40 struct timespec it_value; 41 struct timespec it_interval; 42}; 43 44static struct sigevent fio_timers[MAX_TIMERS]; 45static unsigned int num_timers = 0; 46 47static inline int timer_create(clockid_t clockid, struct sigevent *restrict evp, 48 timer_t *restrict timerid) 49{ 50 int current_timer = num_timers; 51 fio_timers[current_timer] = *evp; 52 num_timers++; 53 54 *timerid = current_timer; 55 return 0; 56} 57 58static void sig_alrm(int signum) 59{ 60 union sigval sv; 61 62 for (int i = 0; i < num_timers; i++) { 63 if (fio_timers[i].sigev_notify_function == NULL) 64 continue; 65 66 if (fio_timers[i].sigev_notify == SIGEV_THREAD) 67 fio_timers[i].sigev_notify_function(sv); 68 else if (fio_timers[i].sigev_notify == SIGEV_SIGNAL) 69 kill(getpid(), fio_timers[i].sigev_signo); 70 } 71} 72 73static inline int timer_settime(timer_t timerid, int flags, 74 const struct itimerspec *value, struct itimerspec *ovalue) 75{ 76 struct sigaction sa; 77 struct itimerval tv; 78 struct itimerval tv_out; 79 int rc; 80 81 tv.it_interval.tv_sec = value->it_interval.tv_sec; 82 tv.it_interval.tv_usec = value->it_interval.tv_nsec / 1000; 83 84 tv.it_value.tv_sec = value->it_value.tv_sec; 85 tv.it_value.tv_usec = value->it_value.tv_nsec / 1000; 86 87 sa.sa_handler = sig_alrm; 88 sigemptyset(&sa.sa_mask); 89 sa.sa_flags = 0; 90 91 rc = sigaction(SIGALRM, &sa, NULL); 92 93 if (!rc) 94 rc = setitimer(ITIMER_REAL, &tv, &tv_out); 95 96 if (!rc && ovalue != NULL) { 97 ovalue->it_interval.tv_sec = tv_out.it_interval.tv_sec; 98 ovalue->it_interval.tv_nsec = tv_out.it_interval.tv_usec * 1000; 99 ovalue->it_value.tv_sec = tv_out.it_value.tv_sec; 100 ovalue->it_value.tv_nsec = tv_out.it_value.tv_usec * 1000; 101 } 102 103 return rc; 104} 105 106static inline int timer_delete(timer_t timer) 107{ 108 return 0; 109} 110 111#define FIO_OS_DIRECTIO 112static inline int fio_set_odirect(int fd) 113{ 114 if (fcntl(fd, F_NOCACHE, 1) == -1) 115 return errno; 116 return 0; 117} 118 119static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) 120{ 121 uint64_t temp = 1; 122 if (ioctl(f->fd, DKIOCGETBLOCKCOUNT, bytes) == -1) 123 return errno; 124 if (ioctl(f->fd, DKIOCGETBLOCKSIZE, &temp) == -1) 125 return errno; 126 (*bytes) *= temp; 127 return 0; 128} 129 130static inline int blockdev_invalidate_cache(struct fio_file *f) 131{ 132 return EINVAL; 133} 134 135static inline unsigned long long os_phys_mem(void) 136{ 137 int mib[2] = { CTL_HW, HW_PHYSMEM }; 138 unsigned long long mem; 139 size_t len = sizeof(mem); 140 141 sysctl(mib, 2, &mem, &len, NULL, 0); 142 return mem; 143} 144#endif 145