1 /* 2 * Copyright (c) 2013 Patrick Kelsey. All rights reserved. 3 * Copyright (C) 2017 THL A29 Limited, a Tencent company. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, this 10 * list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * Derived in part from libuinet's uinet_host_interface.c. 27 */ 28 29 #include <assert.h> 30 #include <errno.h> 31 #include <string.h> 32 #include <stdarg.h> 33 #include <stdint.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <sys/mman.h> 37 #include <sys/stat.h> 38 #include <pthread.h> 39 #include <sched.h> 40 #include <time.h> 41 42 #include <openssl/rand.h> 43 #include <rte_malloc.h> 44 45 #include "ff_host_interface.h" 46 #include "ff_errno.h" 47 48 static struct timespec current_ts; 49 50 void * 51 ff_mmap(void *addr, uint64_t len, int prot, int flags, int fd, uint64_t offset) 52 { 53 //return rte_malloc("", len, 4096); 54 int host_prot; 55 int host_flags; 56 57 assert(ff_PROT_NONE == PROT_NONE); 58 host_prot = 0; 59 if ((prot & ff_PROT_READ) == ff_PROT_READ) host_prot |= PROT_READ; 60 if ((prot & ff_PROT_WRITE) == ff_PROT_WRITE) host_prot |= PROT_WRITE; 61 62 host_flags = 0; 63 if ((flags & ff_MAP_SHARED) == ff_MAP_SHARED) host_flags |= MAP_SHARED; 64 if ((flags & ff_MAP_PRIVATE) == ff_MAP_PRIVATE) host_flags |= MAP_PRIVATE; 65 if ((flags & ff_MAP_ANON) == ff_MAP_ANON) host_flags |= MAP_ANON; 66 67 void *ret = (mmap(addr, len, host_prot, host_flags, fd, offset)); 68 69 if ((uint64_t)ret == -1) { 70 printf("fst mmap failed:%s\n", strerror(errno)); 71 exit(1); 72 } 73 return ret; 74 } 75 76 int 77 ff_munmap(void *addr, uint64_t len) 78 { 79 //rte_free(addr); 80 //return 0; 81 return (munmap(addr, len)); 82 } 83 84 85 void * 86 ff_malloc(uint64_t size) 87 { 88 //return rte_malloc("", size, 0); 89 return (malloc(size)); 90 } 91 92 93 void * 94 ff_calloc(uint64_t number, uint64_t size) 95 { 96 //return rte_calloc("", number, size, 0); 97 return (calloc(number, size)); 98 } 99 100 101 void * 102 ff_realloc(void *p, uint64_t size) 103 { 104 if (size) { 105 //return rte_realloc(p, size, 0); 106 return (realloc(p, size)); 107 } 108 109 return (p); 110 } 111 112 113 void 114 ff_free(void *p) 115 { 116 //rte_free(p); 117 free(p); 118 } 119 120 void panic(const char *, ...) __attribute__((__noreturn__)); 121 122 const char *panicstr = NULL; 123 124 void 125 panic(const char *fmt, ...) 126 { 127 va_list ap; 128 129 va_start(ap, fmt); 130 vprintf(fmt, ap); 131 va_end(ap); 132 133 abort(); 134 } 135 136 void 137 ff_clock_gettime(int id, int64_t *sec, long *nsec) 138 { 139 struct timespec ts; 140 int host_id; 141 int rv; 142 143 switch (id) { 144 case ff_CLOCK_REALTIME: 145 host_id = CLOCK_REALTIME; 146 break; 147 #ifdef CLOCK_MONOTONIC_FAST 148 case ff_CLOCK_MONOTONIC_FAST: 149 host_id = CLOCK_MONOTONIC_FAST; 150 break; 151 #endif 152 case ff_CLOCK_MONOTONIC: 153 default: 154 host_id = CLOCK_MONOTONIC; 155 break; 156 } 157 158 rv = clock_gettime(host_id, &ts); 159 assert(0 == rv); 160 161 *sec = (int64_t)ts.tv_sec; 162 *nsec = (long)ts.tv_nsec; 163 } 164 165 uint64_t 166 ff_clock_gettime_ns(int id) 167 { 168 int64_t sec; 169 long nsec; 170 171 ff_clock_gettime(id, &sec, &nsec); 172 173 return ((uint64_t)sec * ff_NSEC_PER_SEC + nsec); 174 } 175 176 void 177 ff_get_current_time(time_t *sec, long *nsec) 178 { 179 *sec = current_ts.tv_sec; 180 *nsec = current_ts.tv_nsec; 181 } 182 183 void 184 ff_update_current_ts() 185 { 186 int rv = clock_gettime(CLOCK_MONOTONIC, ¤t_ts); 187 assert(rv == 0); 188 } 189 190 void 191 ff_arc4rand(void *ptr, unsigned int len, int reseed) 192 { 193 (void)reseed; 194 195 RAND_pseudo_bytes(ptr, len); 196 } 197 198 uint32_t 199 ff_arc4random(void) 200 { 201 uint32_t ret; 202 ff_arc4rand(&ret, sizeof ret, 0); 203 return ret; 204 } 205 206 int ff_setenv(const char *name, const char *value) 207 { 208 return setenv(name, value, 1); 209 } 210 211 char *ff_getenv(const char *name) 212 { 213 return getenv(name); 214 } 215 216 void ff_os_errno(int error) 217 { 218 switch (error) { 219 case ff_EPERM: errno = EPERM; break; 220 case ff_ENOENT: errno = ENOENT; break; 221 case ff_ESRCH: errno = ESRCH; break; 222 case ff_EINTR: errno = EINTR; break; 223 case ff_EIO: errno = EIO; break; 224 case ff_ENXIO: errno = ENXIO; break; 225 case ff_E2BIG: errno = E2BIG; break; 226 case ff_ENOEXEC: errno = ENOEXEC; break; 227 case ff_EBADF: errno = EBADF; break; 228 case ff_ECHILD: errno = ECHILD; break; 229 case ff_EDEADLK: errno = EDEADLK; break; 230 case ff_ENOMEM: errno = ENOMEM; break; 231 case ff_EACCES: errno = EACCES; break; 232 case ff_EFAULT: errno = EFAULT; break; 233 case ff_ENOTBLK: errno = ENOTBLK; break; 234 case ff_EBUSY: errno = EBUSY; break; 235 case ff_EEXIST: errno = EEXIST; break; 236 case ff_EXDEV: errno = EXDEV; break; 237 case ff_ENODEV: errno = ENODEV; break; 238 case ff_ENOTDIR: errno = ENOTDIR; break; 239 case ff_EISDIR: errno = EISDIR; break; 240 case ff_EINVAL: errno = EINVAL; break; 241 case ff_ENFILE: errno = ENFILE; break; 242 case ff_EMFILE: errno = EMFILE; break; 243 case ff_ENOTTY: errno = ENOTTY; break; 244 case ff_ETXTBSY: errno = ETXTBSY; break; 245 case ff_EFBIG: errno = EFBIG; break; 246 case ff_ENOSPC: errno = ENOSPC; break; 247 case ff_ESPIPE: errno = ESPIPE; break; 248 case ff_EROFS: errno = EROFS; break; 249 case ff_EMLINK: errno = EMLINK; break; 250 case ff_EPIPE: errno = EPIPE; break; 251 case ff_EDOM: errno = EDOM; break; 252 case ff_ERANGE: errno = ERANGE; break; 253 254 /* case ff_EAGAIN: same as EWOULDBLOCK */ 255 case ff_EWOULDBLOCK: errno = EWOULDBLOCK; break; 256 257 case ff_EINPROGRESS: errno = EINPROGRESS; break; 258 case ff_EALREADY: errno = EALREADY; break; 259 case ff_ENOTSOCK: errno = ENOTSOCK; break; 260 case ff_EDESTADDRREQ: errno = EDESTADDRREQ; break; 261 case ff_EMSGSIZE: errno = EMSGSIZE; break; 262 case ff_EPROTOTYPE: errno = EPROTOTYPE; break; 263 case ff_ENOPROTOOPT: errno = ENOPROTOOPT; break; 264 case ff_EPROTONOSUPPORT: errno = EPROTONOSUPPORT; break; 265 case ff_ESOCKTNOSUPPORT: errno = ESOCKTNOSUPPORT; break; 266 267 /* case ff_EOPNOTSUPP: same as ENOTSUP */ 268 case ff_ENOTSUP: errno = ENOTSUP; break; 269 270 case ff_EPFNOSUPPORT: errno = EPFNOSUPPORT; break; 271 case ff_EAFNOSUPPORT: errno = EAFNOSUPPORT; break; 272 case ff_EADDRINUSE: errno = EADDRINUSE; break; 273 case ff_EADDRNOTAVAIL: errno = EADDRNOTAVAIL; break; 274 case ff_ENETDOWN: errno = ENETDOWN; break; 275 case ff_ENETUNREACH: errno = ENETUNREACH; break; 276 case ff_ENETRESET: errno = ENETRESET; break; 277 case ff_ECONNABORTED: errno = ECONNABORTED; break; 278 case ff_ECONNRESET: errno = ECONNRESET; break; 279 case ff_ENOBUFS: errno = ENOBUFS; break; 280 case ff_EISCONN: errno = EISCONN; break; 281 case ff_ENOTCONN: errno = ENOTCONN; break; 282 case ff_ESHUTDOWN: errno = ESHUTDOWN; break; 283 case ff_ETOOMANYREFS: errno = ETOOMANYREFS; break; 284 case ff_ETIMEDOUT: errno = ETIMEDOUT; break; 285 case ff_ECONNREFUSED: errno = ECONNREFUSED; break; 286 case ff_ELOOP: errno = ELOOP; break; 287 case ff_ENAMETOOLONG: errno = ENAMETOOLONG; break; 288 case ff_EHOSTDOWN: errno = EHOSTDOWN; break; 289 case ff_EHOSTUNREACH: errno = EHOSTUNREACH; break; 290 case ff_ENOTEMPTY: errno = ENOTEMPTY; break; 291 case ff_EUSERS: errno = EUSERS; break; 292 case ff_EDQUOT: errno = EDQUOT; break; 293 case ff_ESTALE: errno = ESTALE; break; 294 case ff_EREMOTE: errno = EREMOTE; break; 295 case ff_ENOLCK: errno = ENOLCK; break; 296 case ff_ENOSYS: errno = ENOSYS; break; 297 case ff_EIDRM: errno = EIDRM; break; 298 case ff_ENOMSG: errno = ENOMSG; break; 299 case ff_EOVERFLOW: errno = EOVERFLOW; break; 300 case ff_ECANCELED: errno = ECANCELED; break; 301 case ff_EILSEQ: errno = EILSEQ; break; 302 case ff_EBADMSG: errno = EBADMSG; break; 303 case ff_EMULTIHOP: errno = EMULTIHOP; break; 304 case ff_ENOLINK: errno = ENOLINK; break; 305 case ff_EPROTO: errno = EPROTO; break; 306 default: errno = error; break; 307 } 308 309 } 310 311