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