blob: 6b074cd0997dd479c4c9949f12b18fc59a488163 [file] [log] [blame]
Aaron Carrollec5c6b12012-11-21 10:39:00 +01001#ifndef FIO_OS_ANDROID_H
2#define FIO_OS_ANDROID_H
3
4#define FIO_OS os_android
5
6#include <sys/ioctl.h>
Elliott Hughesabe5ebc2015-02-20 10:34:05 -08007#include <sys/mman.h>
Aaron Carrollec5c6b12012-11-21 10:39:00 +01008#include <sys/uio.h>
9#include <sys/syscall.h>
10#include <sys/vfs.h>
11#include <unistd.h>
12#include <fcntl.h>
13#include <errno.h>
14#include <sched.h>
Aaron Carrollec5c6b12012-11-21 10:39:00 +010015#include <linux/major.h>
Aaron Carrollda52c582013-04-12 09:15:23 +020016#include <asm/byteorder.h>
Mohamad Ayyash3c77c132014-05-14 12:13:31 -070017#include <byteswap.h>
Aaron Carrollec5c6b12012-11-21 10:39:00 +010018
Aaron Carrollec5c6b12012-11-21 10:39:00 +010019#include "binject.h"
20#include "../file.h"
21
22#define FIO_HAVE_DISK_UTIL
Aaron Carrollec5c6b12012-11-21 10:39:00 +010023#define FIO_HAVE_IOSCHED_SWITCH
Aaron Carroll177380a2013-03-12 15:46:10 +110024#define FIO_HAVE_IOPRIO
Aaron Carrollec5c6b12012-11-21 10:39:00 +010025#define FIO_HAVE_ODIRECT
26#define FIO_HAVE_HUGETLB
27#define FIO_HAVE_BLKTRACE
Aaron Carrollec5c6b12012-11-21 10:39:00 +010028#define FIO_HAVE_PSHARED_MUTEX
29#define FIO_HAVE_CL_SIZE
Aaron Carrollec5c6b12012-11-21 10:39:00 +010030#define FIO_HAVE_FS_STAT
31#define FIO_HAVE_TRIM
Aaron Carrollec5c6b12012-11-21 10:39:00 +010032#define FIO_HAVE_GETTID
33#define FIO_USE_GENERIC_INIT_RANDOM_STATE
34#define FIO_HAVE_E4_ENG
35#define FIO_HAVE_BYTEORDER_FUNCS
Aaron Carroll6d0e9f82013-02-12 09:58:14 +010036#define FIO_HAVE_MMAP_HUGE
Olega5e0ee12013-03-12 00:06:53 -070037#define FIO_NO_HAVE_SHM_H
Aaron Carrollec5c6b12012-11-21 10:39:00 +010038
39#define OS_MAP_ANON MAP_ANONYMOUS
40
Aaron Carrollec5c6b12012-11-21 10:39:00 +010041#ifdef MADV_REMOVE
42#define FIO_MADV_FREE MADV_REMOVE
43#endif
Olega5e0ee12013-03-12 00:06:53 -070044#ifndef MAP_HUGETLB
45#define MAP_HUGETLB 0x40000 /* arch specific */
46#endif
Aaron Carrollec5c6b12012-11-21 10:39:00 +010047
48
49/*
50 * The Android NDK doesn't currently export <sys/shm.h>, so define the
51 * necessary stuff here.
52 */
53
54#include <linux/shm.h>
55#define SHM_HUGETLB 04000
56
Akers, Jason B239a11d2013-05-01 21:28:49 +020057#include <stdio.h>
58#include <linux/ashmem.h>
59#include <sys/mman.h>
60
61#define ASHMEM_DEVICE "/dev/ashmem"
62
Aaron Carrollec5c6b12012-11-21 10:39:00 +010063static inline int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf)
64{
Akers, Jason B239a11d2013-05-01 21:28:49 +020065 int ret=0;
66 if (__cmd == IPC_RMID)
67 {
68 int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL);
69 struct ashmem_pin pin = {0 , length};
70 ret = ioctl(__shmid, ASHMEM_UNPIN, &pin);
71 close(__shmid);
72 }
73 return ret;
Aaron Carrollec5c6b12012-11-21 10:39:00 +010074}
75
76static inline int shmget (key_t __key, size_t __size, int __shmflg)
77{
Akers, Jason B239a11d2013-05-01 21:28:49 +020078 int fd,ret;
79 char key[11];
80
81 fd = open(ASHMEM_DEVICE, O_RDWR);
82 if (fd < 0)
83 return fd;
84
85 sprintf(key,"%d",__key);
86 ret = ioctl(fd, ASHMEM_SET_NAME, key);
87 if (ret < 0)
88 goto error;
89
90 ret = ioctl(fd, ASHMEM_SET_SIZE, __size);
91 if (ret < 0)
92 goto error;
93
94 return fd;
95
96error:
97 close(fd);
98 return ret;
Aaron Carrollec5c6b12012-11-21 10:39:00 +010099}
100
101static inline void *shmat (int __shmid, const void *__shmaddr, int __shmflg)
102{
Akers, Jason B239a11d2013-05-01 21:28:49 +0200103 size_t *ptr, size = ioctl(__shmid, ASHMEM_GET_SIZE, NULL);
104 ptr = mmap(NULL, size + sizeof(size_t), PROT_READ | PROT_WRITE, MAP_SHARED, __shmid, 0);
105 *ptr = size; //save size at beginning of buffer, for use with munmap
106 return &ptr[1];
Aaron Carrollec5c6b12012-11-21 10:39:00 +0100107}
108
109static inline int shmdt (const void *__shmaddr)
110{
Akers, Jason B239a11d2013-05-01 21:28:49 +0200111 size_t *ptr, size;
112 ptr = (size_t *)__shmaddr;
113 ptr--;
114 size = *ptr; //find mmap size which we stored at the beginning of the buffer
115 return munmap((void *)ptr, size + sizeof(size_t));
Aaron Carrollec5c6b12012-11-21 10:39:00 +0100116}
117
Aaron Carrollec5c6b12012-11-21 10:39:00 +0100118#define SPLICE_DEF_SIZE (64*1024)
119
Aaron Carroll177380a2013-03-12 15:46:10 +1100120enum {
121 IOPRIO_CLASS_NONE,
122 IOPRIO_CLASS_RT,
123 IOPRIO_CLASS_BE,
124 IOPRIO_CLASS_IDLE,
125};
126
127enum {
128 IOPRIO_WHO_PROCESS = 1,
129 IOPRIO_WHO_PGRP,
130 IOPRIO_WHO_USER,
131};
132
133#define IOPRIO_BITS 16
134#define IOPRIO_CLASS_SHIFT 13
135
Aaron Carrolla415b2c2013-04-12 07:59:01 +0200136static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio)
137{
138 /*
139 * If no class is set, assume BE
140 */
141 if (!ioprio_class)
142 ioprio_class = IOPRIO_CLASS_BE;
143
144 ioprio |= ioprio_class << IOPRIO_CLASS_SHIFT;
145 return syscall(__NR_ioprio_set, which, who, ioprio);
146}
147
Aaron Carrollec5c6b12012-11-21 10:39:00 +0100148#ifndef BLKGETSIZE64
149#define BLKGETSIZE64 _IOR(0x12,114,size_t)
150#endif
151
152#ifndef BLKFLSBUF
153#define BLKFLSBUF _IO(0x12,97)
154#endif
155
156#ifndef BLKDISCARD
157#define BLKDISCARD _IO(0x12,119)
158#endif
159
160static inline int blockdev_invalidate_cache(struct fio_file *f)
161{
162 return ioctl(f->fd, BLKFLSBUF);
163}
164
165static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes)
166{
167 if (!ioctl(f->fd, BLKGETSIZE64, bytes))
168 return 0;
169
170 return errno;
171}
172
173static inline unsigned long long os_phys_mem(void)
174{
175 long pagesize, pages;
176
177 pagesize = sysconf(_SC_PAGESIZE);
178 pages = sysconf(_SC_PHYS_PAGES);
179 if (pages == -1 || pagesize == -1)
180 return 0;
181
182 return (unsigned long long) pages * (unsigned long long) pagesize;
183}
184
185typedef struct { unsigned short r[3]; } os_random_state_t;
186
187static inline void os_random_seed(unsigned long seed, os_random_state_t *rs)
188{
189 rs->r[0] = seed & 0xffff;
190 seed >>= 16;
191 rs->r[1] = seed & 0xffff;
192 seed >>= 16;
193 rs->r[2] = seed & 0xffff;
194 seed48(rs->r);
195}
196
197static inline long os_random_long(os_random_state_t *rs)
198{
199 return nrand48(rs->r);
200}
201
202#ifdef O_NOATIME
203#define FIO_O_NOATIME O_NOATIME
204#else
205#define FIO_O_NOATIME 0
206#endif
207
Mohamad Ayyash3c77c132014-05-14 12:13:31 -0700208#define fio_swap16(x) bswap_16(x)
209#define fio_swap32(x) bswap_32(x)
210#define fio_swap64(x) bswap_64(x)
Aaron Carrollec5c6b12012-11-21 10:39:00 +0100211
212#define CACHE_LINE_FILE \
213 "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size"
214
215static inline int arch_cache_line_size(void)
216{
217 char size[32];
218 int fd, ret;
219
220 fd = open(CACHE_LINE_FILE, O_RDONLY);
221 if (fd < 0)
222 return -1;
223
224 ret = read(fd, size, sizeof(size));
225
226 close(fd);
227
228 if (ret <= 0)
229 return -1;
230 else
231 return atoi(size);
232}
233
234static inline unsigned long long get_fs_size(const char *path)
235{
236 unsigned long long ret;
237 struct statfs s;
238
239 if (statfs(path, &s) < 0)
240 return -1ULL;
241
242 ret = s.f_bsize;
243 ret *= (unsigned long long) s.f_bfree;
244 return ret;
245}
246
247static inline int os_trim(int fd, unsigned long long start,
248 unsigned long long len)
249{
250 uint64_t range[2];
251
252 range[0] = start;
253 range[1] = len;
254
255 if (!ioctl(fd, BLKDISCARD, range))
256 return 0;
257
258 return errno;
259}
260
Elliott Hughesabe5ebc2015-02-20 10:34:05 -0800261#ifdef CONFIG_SCHED_IDLE
262static inline int fio_set_sched_idle(void)
263{
264 struct sched_param p = { .sched_priority = 0, };
265 return sched_setscheduler(gettid(), SCHED_IDLE, &p);
266}
267#endif
268
Aaron Carrollec5c6b12012-11-21 10:39:00 +0100269#endif