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 #include <stdio.h> 65 #include <linux/ashmem.h> 66 #include <sys/mman.h> 67 68 #define ASHMEM_DEVICE "/dev/ashmem" 69 70 static inline int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) 71 { 72 int ret=0; 73 if (__cmd == IPC_RMID) 74 { 75 int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); 76 struct ashmem_pin pin = {0 , length}; 77 ret = ioctl(__shmid, ASHMEM_UNPIN, &pin); 78 close(__shmid); 79 } 80 return ret; 81 } 82 83 static inline int shmget (key_t __key, size_t __size, int __shmflg) 84 { 85 int fd,ret; 86 char key[11]; 87 88 fd = open(ASHMEM_DEVICE, O_RDWR); 89 if (fd < 0) 90 return fd; 91 92 sprintf(key,"%d",__key); 93 ret = ioctl(fd, ASHMEM_SET_NAME, key); 94 if (ret < 0) 95 goto error; 96 97 ret = ioctl(fd, ASHMEM_SET_SIZE, __size); 98 if (ret < 0) 99 goto error; 100 101 return fd; 102 103 error: 104 close(fd); 105 return ret; 106 } 107 108 static inline void *shmat (int __shmid, const void *__shmaddr, int __shmflg) 109 { 110 size_t *ptr, size = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); 111 ptr = mmap(NULL, size + sizeof(size_t), PROT_READ | PROT_WRITE, MAP_SHARED, __shmid, 0); 112 *ptr = size; //save size at beginning of buffer, for use with munmap 113 return &ptr[1]; 114 } 115 116 static inline int shmdt (const void *__shmaddr) 117 { 118 size_t *ptr, size; 119 ptr = (size_t *)__shmaddr; 120 ptr--; 121 size = *ptr; //find mmap size which we stored at the beginning of the buffer 122 return munmap((void *)ptr, size + sizeof(size_t)); 123 } 124 125 #define SPLICE_DEF_SIZE (64*1024) 126 127 enum { 128 IOPRIO_CLASS_NONE, 129 IOPRIO_CLASS_RT, 130 IOPRIO_CLASS_BE, 131 IOPRIO_CLASS_IDLE, 132 }; 133 134 enum { 135 IOPRIO_WHO_PROCESS = 1, 136 IOPRIO_WHO_PGRP, 137 IOPRIO_WHO_USER, 138 }; 139 140 #define IOPRIO_BITS 16 141 #define IOPRIO_CLASS_SHIFT 13 142 143 static inline int ioprio_set(int which, int who, int ioprio_class, int ioprio) 144 { 145 /* 146 * If no class is set, assume BE 147 */ 148 if (!ioprio_class) 149 ioprio_class = IOPRIO_CLASS_BE; 150 151 ioprio |= ioprio_class << IOPRIO_CLASS_SHIFT; 152 return syscall(__NR_ioprio_set, which, who, ioprio); 153 } 154 155 #ifndef BLKGETSIZE64 156 #define BLKGETSIZE64 _IOR(0x12,114,size_t) 157 #endif 158 159 #ifndef BLKFLSBUF 160 #define BLKFLSBUF _IO(0x12,97) 161 #endif 162 163 #ifndef BLKDISCARD 164 #define BLKDISCARD _IO(0x12,119) 165 #endif 166 167 static inline int blockdev_invalidate_cache(struct fio_file *f) 168 { 169 return ioctl(f->fd, BLKFLSBUF); 170 } 171 172 static inline int blockdev_size(struct fio_file *f, unsigned long long *bytes) 173 { 174 if (!ioctl(f->fd, BLKGETSIZE64, bytes)) 175 return 0; 176 177 return errno; 178 } 179 180 static inline unsigned long long os_phys_mem(void) 181 { 182 long pagesize, pages; 183 184 pagesize = sysconf(_SC_PAGESIZE); 185 pages = sysconf(_SC_PHYS_PAGES); 186 if (pages == -1 || pagesize == -1) 187 return 0; 188 189 return (unsigned long long) pages * (unsigned long long) pagesize; 190 } 191 192 typedef struct { unsigned short r[3]; } os_random_state_t; 193 194 static inline void os_random_seed(unsigned long seed, os_random_state_t *rs) 195 { 196 rs->r[0] = seed & 0xffff; 197 seed >>= 16; 198 rs->r[1] = seed & 0xffff; 199 seed >>= 16; 200 rs->r[2] = seed & 0xffff; 201 seed48(rs->r); 202 } 203 204 static inline long os_random_long(os_random_state_t *rs) 205 { 206 return nrand48(rs->r); 207 } 208 209 #ifdef O_NOATIME 210 #define FIO_O_NOATIME O_NOATIME 211 #else 212 #define FIO_O_NOATIME 0 213 #endif 214 215 #define fio_swap16(x) bswap_16(x) 216 #define fio_swap32(x) bswap_32(x) 217 #define fio_swap64(x) bswap_64(x) 218 219 #define CACHE_LINE_FILE \ 220 "/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size" 221 222 static inline int arch_cache_line_size(void) 223 { 224 char size[32]; 225 int fd, ret; 226 227 fd = open(CACHE_LINE_FILE, O_RDONLY); 228 if (fd < 0) 229 return -1; 230 231 ret = read(fd, size, sizeof(size)); 232 233 close(fd); 234 235 if (ret <= 0) 236 return -1; 237 else 238 return atoi(size); 239 } 240 241 static inline unsigned long long get_fs_size(const char *path) 242 { 243 unsigned long long ret; 244 struct statfs s; 245 246 if (statfs(path, &s) < 0) 247 return -1ULL; 248 249 ret = s.f_bsize; 250 ret *= (unsigned long long) s.f_bfree; 251 return ret; 252 } 253 254 static inline int os_trim(int fd, unsigned long long start, 255 unsigned long long len) 256 { 257 uint64_t range[2]; 258 259 range[0] = start; 260 range[1] = len; 261 262 if (!ioctl(fd, BLKDISCARD, range)) 263 return 0; 264 265 return errno; 266 } 267 268 #ifdef CONFIG_SCHED_IDLE 269 static inline int fio_set_sched_idle(void) 270 { 271 struct sched_param p = { .sched_priority = 0, }; 272 return sched_setscheduler(gettid(), SCHED_IDLE, &p); 273 } 274 #endif 275 276 #endif 277