1 #ifndef FIO_OS_ANDROID_H 2 #define FIO_OS_ANDROID_H 3 4 #define FIO_OS os_android 5 6 #include <sys/ioctl.h> 7 #include <sys/mman.h> 8 #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> 15 #include <linux/major.h> 16 #include <asm/byteorder.h> 17 #include <byteswap.h> 18 19 #include "binject.h" 20 #include "../file.h" 21 22 #define FIO_HAVE_DISK_UTIL 23 #define FIO_HAVE_IOSCHED_SWITCH 24 #define FIO_HAVE_IOPRIO 25 #define FIO_HAVE_ODIRECT 26 #define FIO_HAVE_HUGETLB 27 #define FIO_HAVE_BLKTRACE 28 #define FIO_HAVE_PSHARED_MUTEX 29 #define FIO_HAVE_CL_SIZE 30 #define FIO_HAVE_FS_STAT 31 #define FIO_HAVE_TRIM 32 #define FIO_HAVE_GETTID 33 #define FIO_USE_GENERIC_INIT_RANDOM_STATE 34 #define FIO_HAVE_E4_ENG 35 #define FIO_HAVE_BYTEORDER_FUNCS 36 #define FIO_HAVE_MMAP_HUGE 37 #define FIO_NO_HAVE_SHM_H 38 39 #define OS_MAP_ANON MAP_ANONYMOUS 40 41 #ifndef POSIX_MADV_DONTNEED 42 #define posix_madvise madvise 43 #define POSIX_MADV_DONTNEED MADV_DONTNEED 44 #define POSIX_MADV_SEQUENTIAL MADV_SEQUENTIAL 45 #define POSIX_MADV_RANDOM MADV_RANDOM 46 #endif 47 48 #ifdef MADV_REMOVE 49 #define FIO_MADV_FREE MADV_REMOVE 50 #endif 51 #ifndef MAP_HUGETLB 52 #define MAP_HUGETLB 0x40000 /* arch specific */ 53 #endif 54 55 56 /* 57 * The Android NDK doesn't currently export <sys/shm.h>, so define the 58 * necessary stuff here. 59 */ 60 61 #include <linux/shm.h> 62 #define SHM_HUGETLB 04000 63 64 #define shmid_ds shmid64_ds 65 #undef __key 66 67 #include <stdio.h> 68 #include <linux/ashmem.h> 69 #include <sys/mman.h> 70 71 #define ASHMEM_DEVICE "/dev/ashmem" 72 73 static inline int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) 74 { 75 int ret=0; 76 if (__cmd == IPC_RMID) 77 { 78 int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); 79 struct ashmem_pin pin = {0 , length}; 80 ret = ioctl(__shmid, ASHMEM_UNPIN, &pin); 81 close(__shmid); 82 } 83 return ret; 84 } 85 86 static inline int shmget (key_t __key, size_t __size, int __shmflg) 87 { 88 int fd,ret; 89 char key[11]; 90 91 fd = open(ASHMEM_DEVICE, O_RDWR); 92 if (fd < 0) 93 return fd; 94 95 sprintf(key,"%d",__key); 96 ret = ioctl(fd, ASHMEM_SET_NAME, key); 97 if (ret < 0) 98 goto error; 99 100 ret = ioctl(fd, ASHMEM_SET_SIZE, __size); 101 if (ret < 0) 102 goto error; 103 104 return fd; 105 106 error: 107 close(fd); 108 return ret; 109 } 110 111 static inline void *shmat (int __shmid, const void *__shmaddr, int __shmflg) 112 { 113 size_t *ptr, size = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); 114 ptr = mmap(NULL, size + sizeof(size_t), PROT_READ | PROT_WRITE, MAP_SHARED, __shmid, 0); 115 *ptr = size; //save size at beginning of buffer, for use with munmap 116 return &ptr[1]; 117 } 118 119 static inline int shmdt (const void *__shmaddr) 120 { 121 size_t *ptr, size; 122 ptr = (size_t *)__shmaddr; 123 ptr--; 124 size = *ptr; //find mmap size which we stored at the beginning of the buffer 125 return munmap((void *)ptr, size + sizeof(size_t)); 126 } 127 128 #define SPLICE_DEF_SIZE (64*1024) 129 130 enum { 131 IOPRIO_CLASS_NONE, 132 IOPRIO_CLASS_RT, 133 IOPRIO_CLASS_BE, 134 IOPRIO_CLASS_IDLE, 135 }; 136 137 enum { 138 IOPRIO_WHO_PROCESS = 1, 139 IOPRIO_WHO_PGRP, 140 IOPRIO_WHO_USER, 141 }; 142 143 #define IOPRIO_BITS 16 144 #define IOPRIO_CLASS_SHIFT 13 145 146 static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio) 147 { 148 /* 149 * If no class is set, assume BE 150 */ 151 if (!ioprio_class) 152 ioprio_class = IOPRIO_CLASS_BE; 153 154 ioprio |= ioprio_class << IOPRIO_CLASS_SHIFT; 155 return syscall(__NR_ioprio_set, which, who, ioprio); 156 } 157 158 #ifndef BLKGETSIZE64 159 #define BLKGETSIZE64 _IOR(0x12,114,size_t) 160 #endif 161 162 #ifndef BLKFLSBUF 163 #define BLKFLSBUF _IO(0x12,97) 164 #endif 165 166 #ifndef BLKDISCARD 167 #define BLKDISCARD _IO(0x12,119) 168 #endif 169 170 static inline int blockdev_invalidate_cache(struct fio_file *f) 171 { 172 return ioctl(f->fd, BLKFLSBUF); 173 } 174 175 static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) 176 { 177 if (!ioctl(f->fd, BLKGETSIZE64, bytes)) 178 return 0; 179 180 return errno; 181 } 182 183 static inline unsigned long long os_phys_mem(void) 184 { 185 long pagesize, pages; 186 187 pagesize = sysconf(_SC_PAGESIZE); 188 pages = sysconf(_SC_PHYS_PAGES); 189 if (pages == -1 || pagesize == -1) 190 return 0; 191 192 return (unsigned long long) pages * (unsigned long long) pagesize; 193 } 194 195 typedef struct { unsigned short r[3]; } os_random_state_t; 196 197 static inline void os_random_seed(unsigned long seed, os_random_state_t *rs) 198 { 199 rs->r[0] = seed & 0xffff; 200 seed >>= 16; 201 rs->r[1] = seed & 0xffff; 202 seed >>= 16; 203 rs->r[2] = seed & 0xffff; 204 seed48(rs->r); 205 } 206 207 static inline long os_random_long(os_random_state_t *rs) 208 { 209 return nrand48(rs->r); 210 } 211 212 #ifdef O_NOATIME 213 #define FIO_O_NOATIME O_NOATIME 214 #else 215 #define FIO_O_NOATIME 0 216 #endif 217 218 #define fio_swap16(x) bswap_16(x) 219 #define fio_swap32(x) bswap_32(x) 220 #define fio_swap64(x) bswap_64(x) 221 222 #define CACHE_LINE_FILE \ 223 "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size" 224 225 static inline int arch_cache_line_size(void) 226 { 227 char size[32]; 228 int fd, ret; 229 230 fd = open(CACHE_LINE_FILE, O_RDONLY); 231 if (fd < 0) 232 return -1; 233 234 ret = read(fd, size, sizeof(size)); 235 236 close(fd); 237 238 if (ret <= 0) 239 return -1; 240 else 241 return atoi(size); 242 } 243 244 static inline unsigned long long get_fs_size(const char *path) 245 { 246 unsigned long long ret; 247 struct statfs s; 248 249 if (statfs(path, &s) < 0) 250 return -1ULL; 251 252 ret = s.f_bsize; 253 ret *= (unsigned long long) s.f_bfree; 254 return ret; 255 } 256 257 static inline int os_trim(int fd, unsigned long long start, 258 unsigned long long len) 259 { 260 uint64_t range[2]; 261 262 range[0] = start; 263 range[1] = len; 264 265 if (!ioctl(fd, BLKDISCARD, range)) 266 return 0; 267 268 return errno; 269 } 270 271 #ifdef CONFIG_SCHED_IDLE 272 static inline int fio_set_sched_idle(void) 273 { 274 struct sched_param p = { .sched_priority = 0, }; 275 return sched_setscheduler(gettid(), SCHED_IDLE, &p); 276 } 277 #endif 278 279 #endif 280