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 void * 49 ff_mmap(void *addr, uint64_t len, int prot, int flags, int fd, uint64_t offset) 50 { 51 //return rte_malloc("", len, 4096); 52 int host_prot; 53 int host_flags; 54 55 assert(ff_PROT_NONE == PROT_NONE); 56 host_prot = 0; 57 if ((prot & ff_PROT_READ) == ff_PROT_READ) host_prot |= PROT_READ; 58 if ((prot & ff_PROT_WRITE) == ff_PROT_WRITE) host_prot |= PROT_WRITE; 59 60 host_flags = 0; 61 if ((flags & ff_MAP_SHARED) == ff_MAP_SHARED) host_flags |= MAP_SHARED; 62 if ((flags & ff_MAP_PRIVATE) == ff_MAP_PRIVATE) host_flags |= MAP_PRIVATE; 63 if ((flags & ff_MAP_ANON) == ff_MAP_ANON) host_flags |= MAP_ANON; 64 65 void *ret = (mmap(addr, len, host_prot, host_flags, fd, offset)); 66 67 if ((uint64_t)ret == -1) { 68 printf("fst mmap failed:%s\n", strerror(errno)); 69 exit(1); 70 } 71 return ret; 72 } 73 74 int 75 ff_munmap(void *addr, uint64_t len) 76 { 77 //rte_free(addr); 78 //return 0; 79 return (munmap(addr, len)); 80 } 81 82 83 void * 84 ff_malloc(uint64_t size) 85 { 86 //return rte_malloc("", size, 0); 87 return (malloc(size)); 88 } 89 90 91 void * 92 ff_calloc(uint64_t number, uint64_t size) 93 { 94 //return rte_calloc("", number, size, 0); 95 return (calloc(number, size)); 96 } 97 98 99 void * 100 ff_realloc(void *p, uint64_t size) 101 { 102 if (size) { 103 //return rte_realloc(p, size, 0); 104 return (realloc(p, size)); 105 } 106 107 return (p); 108 } 109 110 111 void 112 ff_free(void *p) 113 { 114 //rte_free(p); 115 free(p); 116 } 117 118 void panic(const char *, ...) __attribute__((__noreturn__)); 119 120 const char *panicstr = NULL; 121 122 void 123 panic(const char *fmt, ...) 124 { 125 va_list ap; 126 127 va_start(ap, fmt); 128 vprintf(fmt, ap); 129 va_end(ap); 130 131 abort(); 132 } 133 134 void 135 ff_clock_gettime(int id, int64_t *sec, long *nsec) 136 { 137 struct timespec ts; 138 int host_id; 139 int rv; 140 141 switch (id) { 142 case ff_CLOCK_REALTIME: 143 host_id = CLOCK_REALTIME; 144 break; 145 #ifdef CLOCK_MONOTONIC_FAST 146 case ff_CLOCK_MONOTONIC_FAST: 147 host_id = CLOCK_MONOTONIC_FAST; 148 break; 149 #endif 150 case ff_CLOCK_MONOTONIC: 151 default: 152 host_id = CLOCK_MONOTONIC; 153 break; 154 } 155 156 rv = clock_gettime(host_id, &ts); 157 assert(0 == rv); 158 159 *sec = (int64_t)ts.tv_sec; 160 *nsec = (long)ts.tv_nsec; 161 } 162 163 uint64_t 164 ff_clock_gettime_ns(int id) 165 { 166 int64_t sec; 167 long nsec; 168 169 ff_clock_gettime(id, &sec, &nsec); 170 171 return ((uint64_t)sec * ff_NSEC_PER_SEC + nsec); 172 } 173 174 /* 175 * Sleeps for at least the given number of nanoseconds and returns 0, 176 * unless there is a non-EINTR failure, in which case a non-zero value is 177 * returned. 178 */ 179 int 180 ff_nanosleep(uint64_t nsecs) 181 { 182 struct timespec ts; 183 struct timespec rts; 184 int rv; 185 186 ts.tv_sec = nsecs / ff_NSEC_PER_SEC; 187 ts.tv_nsec = nsecs % ff_NSEC_PER_SEC; 188 while ((-1 == (rv = nanosleep(&ts, &rts))) && (EINTR == errno)) { 189 ts = rts; 190 } 191 if (-1 == rv) { 192 rv = errno; 193 } 194 195 return (rv); 196 } 197 198 void 199 ff_arc4rand(void *ptr, unsigned int len, int reseed) 200 { 201 (void)reseed; 202 203 RAND_pseudo_bytes(ptr, len); 204 } 205 206 uint32_t 207 ff_arc4random(void) 208 { 209 uint32_t ret; 210 ff_arc4rand(&ret, sizeof ret, 0); 211 return ret; 212 } 213 214 int ff_setenv(const char *name, const char *value) 215 { 216 return setenv(name, value, 1); 217 } 218 219 char *ff_getenv(const char *name) 220 { 221 return getenv(name); 222 } 223 224 void ff_os_errno(int error) 225 { 226 switch (error) { 227 case ff_EPERM: errno = EPERM; break; 228 case ff_ENOENT: errno = ENOENT; break; 229 case ff_ESRCH: errno = ESRCH; break; 230 case ff_EINTR: errno = EINTR; break; 231 case ff_EIO: errno = EIO; break; 232 case ff_ENXIO: errno = ENXIO; break; 233 case ff_E2BIG: errno = E2BIG; break; 234 case ff_ENOEXEC: errno = ENOEXEC; break; 235 case ff_EBADF: errno = EBADF; break; 236 case ff_ECHILD: errno = ECHILD; break; 237 case ff_EDEADLK: errno = EDEADLK; break; 238 case ff_ENOMEM: errno = ENOMEM; break; 239 case ff_EACCES: errno = EACCES; break; 240 case ff_EFAULT: errno = EFAULT; break; 241 case ff_ENOTBLK: errno = ENOTBLK; break; 242 case ff_EBUSY: errno = EBUSY; break; 243 case ff_EEXIST: errno = EEXIST; break; 244 case ff_EXDEV: errno = EXDEV; break; 245 case ff_ENODEV: errno = ENODEV; break; 246 case ff_ENOTDIR: errno = ENOTDIR; break; 247 case ff_EISDIR: errno = EISDIR; break; 248 case ff_EINVAL: errno = EINVAL; break; 249 case ff_ENFILE: errno = ENFILE; break; 250 case ff_EMFILE: errno = EMFILE; break; 251 case ff_ENOTTY: errno = ENOTTY; break; 252 case ff_ETXTBSY: errno = ETXTBSY; break; 253 case ff_EFBIG: errno = EFBIG; break; 254 case ff_ENOSPC: errno = ENOSPC; break; 255 case ff_ESPIPE: errno = ESPIPE; break; 256 case ff_EROFS: errno = EROFS; break; 257 case ff_EMLINK: errno = EMLINK; break; 258 case ff_EPIPE: errno = EPIPE; break; 259 case ff_EDOM: errno = EDOM; break; 260 case ff_ERANGE: errno = ERANGE; break; 261 262 /* case ff_EAGAIN: same as EWOULDBLOCK */ 263 case ff_EWOULDBLOCK: errno = EWOULDBLOCK; break; 264 265 case ff_EINPROGRESS: errno = EINPROGRESS; break; 266 case ff_EALREADY: errno = EALREADY; break; 267 case ff_ENOTSOCK: errno = ENOTSOCK; break; 268 case ff_EDESTADDRREQ: errno = EDESTADDRREQ; break; 269 case ff_EMSGSIZE: errno = EMSGSIZE; break; 270 case ff_EPROTOTYPE: errno = EPROTOTYPE; break; 271 case ff_ENOPROTOOPT: errno = ENOPROTOOPT; break; 272 case ff_EPROTONOSUPPORT: errno = EPROTONOSUPPORT; break; 273 case ff_ESOCKTNOSUPPORT: errno = ESOCKTNOSUPPORT; break; 274 275 /* case ff_EOPNOTSUPP: same as ENOTSUP */ 276 case ff_ENOTSUP: errno = ENOTSUP; break; 277 278 case ff_EPFNOSUPPORT: errno = EPFNOSUPPORT; break; 279 case ff_EAFNOSUPPORT: errno = EAFNOSUPPORT; break; 280 case ff_EADDRINUSE: errno = EADDRINUSE; break; 281 case ff_EADDRNOTAVAIL: errno = EADDRNOTAVAIL; break; 282 case ff_ENETDOWN: errno = ENETDOWN; break; 283 case ff_ENETUNREACH: errno = ENETUNREACH; break; 284 case ff_ENETRESET: errno = ENETRESET; break; 285 case ff_ECONNABORTED: errno = ECONNABORTED; break; 286 case ff_ECONNRESET: errno = ECONNRESET; break; 287 case ff_ENOBUFS: errno = ENOBUFS; break; 288 case ff_EISCONN: errno = EISCONN; break; 289 case ff_ENOTCONN: errno = ENOTCONN; break; 290 case ff_ESHUTDOWN: errno = ESHUTDOWN; break; 291 case ff_ETOOMANYREFS: errno = ETOOMANYREFS; break; 292 case ff_ETIMEDOUT: errno = ETIMEDOUT; break; 293 case ff_ECONNREFUSED: errno = ECONNREFUSED; break; 294 case ff_ELOOP: errno = ELOOP; break; 295 case ff_ENAMETOOLONG: errno = ENAMETOOLONG; break; 296 case ff_EHOSTDOWN: errno = EHOSTDOWN; break; 297 case ff_EHOSTUNREACH: errno = EHOSTUNREACH; break; 298 case ff_ENOTEMPTY: errno = ENOTEMPTY; break; 299 case ff_EUSERS: errno = EUSERS; break; 300 case ff_EDQUOT: errno = EDQUOT; break; 301 case ff_ESTALE: errno = ESTALE; break; 302 case ff_EREMOTE: errno = EREMOTE; break; 303 case ff_ENOLCK: errno = ENOLCK; break; 304 case ff_ENOSYS: errno = ENOSYS; break; 305 case ff_EIDRM: errno = EIDRM; break; 306 case ff_ENOMSG: errno = ENOMSG; break; 307 case ff_EOVERFLOW: errno = EOVERFLOW; break; 308 case ff_ECANCELED: errno = ECANCELED; break; 309 case ff_EILSEQ: errno = EILSEQ; break; 310 case ff_EBADMSG: errno = EBADMSG; break; 311 case ff_EMULTIHOP: errno = EMULTIHOP; break; 312 case ff_ENOLINK: errno = ENOLINK; break; 313 case ff_EPROTO: errno = EPROTO; break; 314 default: errno = error; break; 315 } 316 317 } 318 319