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