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