Add low water mark for queuing depth
[fio.git] / os-linux.h
1 #ifndef FIO_OS_LINUX_H
2 #define FIO_OS_LINUX_H
3
4 #include <sys/ioctl.h>
5 #include <sys/uio.h>
6 #include <sys/syscall.h>
7 #include <unistd.h>
8 #include <fcntl.h>
9 #include <linux/unistd.h>
10
11 #define FIO_HAVE_LIBAIO
12 #define FIO_HAVE_POSIXAIO
13 #define FIO_HAVE_FADVISE
14 #define FIO_HAVE_CPU_AFFINITY
15 #define FIO_HAVE_DISK_UTIL
16 #define FIO_HAVE_SGIO
17 #define FIO_HAVE_IOPRIO
18 #define FIO_HAVE_SPLICE
19 #define FIO_HAVE_IOSCHED_SWITCH
20 #define FIO_HAVE_ODIRECT
21 #define FIO_HAVE_HUGETLB
22
23 /*
24  * Only for x86 currently
25  */
26 #if defined(__i386__)
27 #define FIO_HAVE_SYSLET
28 #endif
29
30 #define OS_MAP_ANON             (MAP_ANONYMOUS)
31
32 typedef cpu_set_t os_cpu_mask_t;
33 typedef struct drand48_data os_random_state_t;
34
35 /*
36  * we want fadvise64 really, but it's so tangled... later
37  */
38 #define fadvise(fd, off, len, advice)   \
39         posix_fadvise((fd), (off_t)(off), (len), (advice))
40
41 #define fio_setaffinity(td)             \
42         sched_setaffinity((td)->pid, sizeof((td)->cpumask), &(td)->cpumask)
43 #define fio_getaffinity(pid, ptr)       \
44         sched_getaffinity((pid), sizeof(cpu_set_t), (ptr))
45
46 static inline int ioprio_set(int which, int who, int ioprio)
47 {
48         return syscall(__NR_ioprio_set, which, who, ioprio);
49 }
50
51 /*
52  * Just check for SPLICE_F_MOVE, if that isn't there, assume the others
53  * aren't either.
54  */
55 #ifndef SPLICE_F_MOVE
56 #define SPLICE_F_MOVE   (0x01)  /* move pages instead of copying */
57 #define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
58                                  /* we may still block on the fd we splice */
59                                  /* from/to, of course */
60 #define SPLICE_F_MORE   (0x04)  /* expect more data */
61 #define SPLICE_F_GIFT   (0x08)  /* pages passed in are a gift */
62
63 static inline int splice(int fdin, loff_t *off_in, int fdout, loff_t *off_out,
64                          size_t len, unsigned long flags)
65 {
66         return syscall(__NR_sys_splice, fdin, off_in, fdout, off_out, len, flags);
67 }
68
69 static inline int tee(int fdin, int fdout, size_t len, unsigned int flags)
70 {
71         return syscall(__NR_sys_tee, fdin, fdout, len, flags);
72 }
73
74 static inline int vmsplice(int fd, const struct iovec *iov,
75                            unsigned long nr_segs, unsigned int flags)
76 {
77         return syscall(__NR_sys_vmsplice, fd, iov, nr_segs, flags);
78 }
79 #endif
80
81 #define SPLICE_DEF_SIZE (64*1024)
82
83 #ifdef FIO_HAVE_SYSLET
84 /*
85  * syslet stuff
86  */
87 static inline long async_register(void *uah, unsigned int len)
88 {
89         return syscall(__NR_async_register, uah, len);
90 }
91
92 static inline void *async_exec(void *data)
93 {
94         return (void *) syscall(__NR_async_exec, data);
95 }
96
97 static inline long async_wait(unsigned long min_events)
98 {
99         return syscall(__NR_async_wait, min_events);
100 }
101
102 static inline long async_unregister(void *uah, unsigned int len)
103 {
104         return syscall(__NR_async_unregister, uah, len);
105 }
106
107 static inline long umem_add(unsigned long *uptr, unsigned long inc)
108 {
109         return syscall(__NR_umem_add, uptr, inc);
110 }
111 #endif /* FIO_HAVE_SYSLET */
112
113 enum {
114         IOPRIO_WHO_PROCESS = 1,
115         IOPRIO_WHO_PGRP,
116         IOPRIO_WHO_USER,
117 };
118
119 #define IOPRIO_CLASS_SHIFT      13
120
121 #ifndef BLKGETSIZE64
122 #define BLKGETSIZE64    _IOR(0x12,114,size_t)
123 #endif
124
125 #ifndef BLKFLSBUF
126 #define BLKFLSBUF       _IO(0x12,97)
127 #endif
128
129 static inline int blockdev_invalidate_cache(int fd)
130 {
131         if (!ioctl(fd, BLKFLSBUF))
132                 return 0;
133
134         return errno;
135 }
136
137 static inline int blockdev_size(int fd, unsigned long long *bytes)
138 {
139         if (!ioctl(fd, BLKGETSIZE64, bytes))
140                 return 0;
141
142         return errno;
143 }
144
145 static inline unsigned long long os_phys_mem(void)
146 {
147         long pagesize, pages;
148
149         pagesize = sysconf(_SC_PAGESIZE);
150         pages = sysconf(_SC_PHYS_PAGES);
151         if (pages == -1 || pagesize == -1)
152                 return 0;
153
154         return (unsigned long long) pages * (unsigned long long) pagesize;
155 }
156
157 static inline void os_random_seed(unsigned long seed, os_random_state_t *rs)
158 {
159         srand48_r(seed, rs);
160 }
161
162 static inline long os_random_long(os_random_state_t *rs)
163 {
164         long val;
165
166         lrand48_r(rs, &val);
167         return val;
168 }
169
170 static inline double os_random_double(os_random_state_t *rs)
171 {
172         double val;
173
174         drand48_r(rs, &val);
175         return val;
176 }
177
178 #endif