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