1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 35 #ifndef __LIBOCF_ENV_H__ 36 #define __LIBOCF_ENV_H__ 37 38 #ifndef _GNU_SOURCE 39 #define _GNU_SOURCE 40 #endif 41 #ifndef __USE_GNU 42 #define __USE_GNU 43 #endif 44 45 #include <linux/limits.h> 46 #include <linux/stddef.h> 47 48 #include "spdk/stdinc.h" 49 #include "spdk/likely.h" 50 #include "spdk/env.h" 51 #include "spdk/util.h" 52 #include "spdk_internal/log.h" 53 54 #include "ocf_env_list.h" 55 #include "ocf/ocf_err.h" 56 57 typedef uint8_t u8; 58 typedef uint16_t u16; 59 typedef uint32_t u32; 60 typedef uint64_t u64; 61 62 typedef uint64_t sector_t; 63 64 #define __packed __attribute__((packed)) 65 #define __aligned(x) __attribute__((aligned(x))) 66 67 /* linux sector 512-bytes */ 68 #define ENV_SECTOR_SHIFT 9 69 #define ENV_SECTOR_SIZE (1<<ENV_SECTOR_SHIFT) 70 #define BYTES_TO_SECTOR(x) ((x) >> ENV_SECTOR_SHIFT) 71 72 /* *** MEMORY MANAGEMENT *** */ 73 74 #define ENV_MEM_NORMAL 0 75 #define ENV_MEM_NOIO 0 76 #define ENV_MEM_ATOMIC 0 77 78 #define likely spdk_likely 79 #define unlikely spdk_unlikely 80 81 #define min(x, y) MIN(x, y) 82 #ifndef MIN 83 #define MIN(x, y) spdk_min(x, y) 84 #endif 85 86 #define ARRAY_SIZE(x) SPDK_COUNTOF(x) 87 88 /* LOGGING */ 89 #define ENV_PRIu64 PRIu64 90 91 #define ENV_WARN(cond, fmt, args...) ({ \ 92 if (spdk_unlikely((uintptr_t)(cond))) \ 93 SPDK_NOTICELOG("WARNING" fmt, ##args); \ 94 }) 95 96 #define ENV_WARN_ON(cond) ({ \ 97 if (spdk_unlikely((uintptr_t)(cond))) \ 98 SPDK_NOTICELOG("WARNING\n"); \ 99 }) 100 101 #define ENV_BUG() ({ \ 102 SPDK_ERRLOG("BUG\n"); \ 103 assert(0); \ 104 abort(); \ 105 }) 106 107 #define ENV_BUG_ON(cond) ({ \ 108 if (spdk_unlikely((uintptr_t)(cond))) { \ 109 SPDK_ERRLOG("BUG\n"); \ 110 assert(0); \ 111 abort(); \ 112 } \ 113 }) 114 115 #define ENV_BUILD_BUG_ON(cond) _Static_assert(!(cond), "static "\ 116 "assertion failure") 117 118 #define container_of(ptr, type, member) SPDK_CONTAINEROF(ptr, type, member) 119 120 static inline void *env_malloc(size_t size, int flags) 121 { 122 return spdk_malloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY, 123 SPDK_MALLOC_DMA); 124 } 125 126 static inline void *env_zalloc(size_t size, int flags) 127 { 128 return spdk_zmalloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY, 129 SPDK_MALLOC_DMA); 130 } 131 132 static inline void env_free(const void *ptr) 133 { 134 return spdk_free((void *)ptr); 135 } 136 137 static inline void *env_vmalloc(size_t size) 138 { 139 return spdk_malloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY, 140 SPDK_MALLOC_DMA); 141 } 142 143 static inline void *env_vzalloc(size_t size) 144 { 145 /* TODO: raw_ram init can request huge amount of memory to store 146 * hashtable in it. need to ensure that allocation succedds */ 147 return spdk_zmalloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY, 148 SPDK_MALLOC_DMA); 149 } 150 151 static inline void *env_vzalloc_flags(size_t size, int flags) 152 { 153 return env_vzalloc(size); 154 } 155 156 static inline void *env_secure_alloc(size_t size) 157 { 158 return spdk_zmalloc(size, 0, NULL, SPDK_ENV_LCORE_ID_ANY, 159 SPDK_MALLOC_DMA); 160 } 161 162 static inline void env_secure_free(const void *ptr, size_t size) 163 { 164 return spdk_free((void *)ptr); 165 } 166 167 static inline void env_vfree(const void *ptr) 168 { 169 return spdk_free((void *)ptr); 170 } 171 172 static inline uint64_t env_get_free_memory(void) 173 { 174 /* TODO: do we need implementation for this function? */ 175 return sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES); 176 } 177 178 /* *** ALLOCATOR *** */ 179 180 #define OCF_ALLOCATOR_NAME_MAX 128 181 182 typedef struct { 183 struct spdk_mempool *mempool; 184 size_t element_size; 185 } env_allocator; 186 187 env_allocator *env_allocator_create(uint32_t size, const char *name); 188 189 void env_allocator_destroy(env_allocator *allocator); 190 191 void *env_allocator_new(env_allocator *allocator); 192 193 void env_allocator_del(env_allocator *allocator, void *item); 194 195 uint32_t env_allocator_item_count(env_allocator *allocator); 196 197 /* *** MUTEX *** */ 198 199 typedef struct { 200 pthread_mutex_t m; 201 } env_mutex; 202 203 static inline int env_mutex_init(env_mutex *mutex) 204 { 205 return !!pthread_mutex_init(&mutex->m, NULL); 206 } 207 208 static inline void env_mutex_lock(env_mutex *mutex) 209 { 210 ENV_BUG_ON(pthread_mutex_lock(&mutex->m)); 211 } 212 213 static inline int env_mutex_lock_interruptible(env_mutex *mutex) 214 { 215 env_mutex_lock(mutex); 216 return 0; 217 } 218 219 static inline int env_mutex_trylock(env_mutex *mutex) 220 { 221 return pthread_mutex_trylock(&mutex->m) ? -OCF_ERR_NO_LOCK : 0; 222 } 223 224 static inline void env_mutex_unlock(env_mutex *mutex) 225 { 226 ENV_BUG_ON(pthread_mutex_unlock(&mutex->m)); 227 } 228 229 static inline int env_mutex_is_locked(env_mutex *mutex) 230 { 231 if (env_mutex_trylock(mutex) == 0) { 232 env_mutex_unlock(mutex); 233 return 0; 234 } 235 236 return 1; 237 } 238 239 static inline int env_mutex_destroy(env_mutex *mutex) 240 { 241 if (pthread_mutex_destroy(&mutex->m)) { 242 return 1; 243 } 244 245 return 0; 246 } 247 248 /* *** RECURSIVE MUTEX *** */ 249 250 typedef env_mutex env_rmutex; 251 252 static inline int env_rmutex_init(env_rmutex *rmutex) 253 { 254 pthread_mutexattr_t attr; 255 256 pthread_mutexattr_init(&attr); 257 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 258 pthread_mutex_init(&rmutex->m, &attr); 259 260 return 0; 261 } 262 263 static inline void env_rmutex_lock(env_rmutex *rmutex) 264 { 265 env_mutex_lock(rmutex); 266 } 267 268 static inline int env_rmutex_lock_interruptible(env_rmutex *rmutex) 269 { 270 return env_mutex_lock_interruptible(rmutex); 271 } 272 273 static inline int env_rmutex_trylock(env_rmutex *rmutex) 274 { 275 return env_mutex_trylock(rmutex); 276 } 277 278 static inline void env_rmutex_unlock(env_rmutex *rmutex) 279 { 280 env_mutex_unlock(rmutex); 281 } 282 283 static inline int env_rmutex_is_locked(env_rmutex *rmutex) 284 { 285 return env_mutex_is_locked(rmutex); 286 } 287 288 static inline int env_rmutex_destroy(env_rmutex *rmutex) 289 { 290 return env_mutex_destroy(rmutex); 291 } 292 293 /* *** RW SEMAPHORE *** */ 294 typedef struct { 295 pthread_rwlock_t lock; 296 } env_rwsem; 297 298 static inline int env_rwsem_init(env_rwsem *s) 299 { 300 return !!pthread_rwlock_init(&s->lock, NULL); 301 } 302 303 static inline void env_rwsem_up_read(env_rwsem *s) 304 { 305 ENV_BUG_ON(pthread_rwlock_unlock(&s->lock)); 306 } 307 308 static inline void env_rwsem_down_read(env_rwsem *s) 309 { 310 ENV_BUG_ON(pthread_rwlock_rdlock(&s->lock)); 311 } 312 313 static inline int env_rwsem_down_read_trylock(env_rwsem *s) 314 { 315 return pthread_rwlock_tryrdlock(&s->lock) ? -OCF_ERR_NO_LOCK : 0; 316 } 317 318 static inline void env_rwsem_up_write(env_rwsem *s) 319 { 320 ENV_BUG_ON(pthread_rwlock_unlock(&s->lock)); 321 } 322 323 static inline void env_rwsem_down_write(env_rwsem *s) 324 { 325 ENV_BUG_ON(pthread_rwlock_wrlock(&s->lock)); 326 } 327 328 static inline int env_rwsem_down_write_trylock(env_rwsem *s) 329 { 330 return pthread_rwlock_trywrlock(&s->lock) ? -OCF_ERR_NO_LOCK : 0; 331 } 332 333 static inline int env_rwsem_is_locked(env_rwsem *s) 334 { 335 if (env_rwsem_down_read_trylock(s) == 0) { 336 env_rwsem_up_read(s); 337 return 0; 338 } 339 340 return 1; 341 } 342 343 static inline int env_rwsem_down_read_interruptible(env_rwsem *s) 344 { 345 return pthread_rwlock_rdlock(&s->lock); 346 } 347 static inline int env_rwsem_down_write_interruptible(env_rwsem *s) 348 { 349 return pthread_rwlock_wrlock(&s->lock); 350 } 351 352 static inline int env_rwsem_destroy(env_rwsem *s) 353 { 354 return pthread_rwlock_destroy(&s->lock); 355 } 356 357 /* *** ATOMIC VARIABLES *** */ 358 359 typedef int env_atomic; 360 361 typedef long env_atomic64; 362 363 #ifndef atomic_read 364 #define atomic_read(ptr) (*(__typeof__(*ptr) *volatile) (ptr)) 365 #endif 366 367 #ifndef atomic_set 368 #define atomic_set(ptr, i) ((*(__typeof__(*ptr) *volatile) (ptr)) = (i)) 369 #endif 370 371 #define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1)) 372 #define atomic_dec(ptr) ((void) __sync_fetch_and_add(ptr, -1)) 373 #define atomic_add(ptr, n) ((void) __sync_fetch_and_add(ptr, n)) 374 #define atomic_sub(ptr, n) ((void) __sync_fetch_and_sub(ptr, n)) 375 376 #define atomic_cmpxchg __sync_val_compare_and_swap 377 378 static inline int env_atomic_read(const env_atomic *a) 379 { 380 return atomic_read(a); 381 } 382 383 static inline void env_atomic_set(env_atomic *a, int i) 384 { 385 atomic_set(a, i); 386 } 387 388 static inline void env_atomic_add(int i, env_atomic *a) 389 { 390 atomic_add(a, i); 391 } 392 393 static inline void env_atomic_sub(int i, env_atomic *a) 394 { 395 atomic_sub(a, i); 396 } 397 398 static inline bool env_atomic_sub_and_test(int i, env_atomic *a) 399 { 400 return __sync_sub_and_fetch(a, i) == 0; 401 } 402 403 static inline void env_atomic_inc(env_atomic *a) 404 { 405 atomic_inc(a); 406 } 407 408 static inline void env_atomic_dec(env_atomic *a) 409 { 410 atomic_dec(a); 411 } 412 413 static inline bool env_atomic_dec_and_test(env_atomic *a) 414 { 415 return __sync_sub_and_fetch(a, 1) == 0; 416 } 417 418 static inline bool env_atomic_inc_and_test(env_atomic *a) 419 { 420 return __sync_add_and_fetch(a, 1) == 0; 421 } 422 423 static inline int env_atomic_add_return(int i, env_atomic *a) 424 { 425 return __sync_add_and_fetch(a, i); 426 } 427 428 static inline int env_atomic_sub_return(int i, env_atomic *a) 429 { 430 return __sync_sub_and_fetch(a, i); 431 } 432 433 static inline int env_atomic_inc_return(env_atomic *a) 434 { 435 return env_atomic_add_return(1, a); 436 } 437 438 static inline int env_atomic_dec_return(env_atomic *a) 439 { 440 return env_atomic_sub_return(1, a); 441 } 442 443 static inline int env_atomic_cmpxchg(env_atomic *a, int old, int new_value) 444 { 445 return atomic_cmpxchg(a, old, new_value); 446 } 447 448 static inline int env_atomic_add_unless(env_atomic *a, int i, int u) 449 { 450 int c, old; 451 c = env_atomic_read(a); 452 for (;;) { 453 if (spdk_unlikely(c == (u))) { 454 break; 455 } 456 old = env_atomic_cmpxchg((a), c, c + (i)); 457 if (spdk_likely(old == c)) { 458 break; 459 } 460 c = old; 461 } 462 return c != (u); 463 } 464 465 static inline long env_atomic64_read(const env_atomic64 *a) 466 { 467 return atomic_read(a); 468 } 469 470 static inline void env_atomic64_set(env_atomic64 *a, long i) 471 { 472 atomic_set(a, i); 473 } 474 475 static inline void env_atomic64_add(long i, env_atomic64 *a) 476 { 477 atomic_add(a, i); 478 } 479 480 static inline void env_atomic64_sub(long i, env_atomic64 *a) 481 { 482 atomic_sub(a, i); 483 } 484 485 static inline void env_atomic64_inc(env_atomic64 *a) 486 { 487 atomic_inc(a); 488 } 489 490 static inline void env_atomic64_dec(env_atomic64 *a) 491 { 492 atomic_dec(a); 493 } 494 495 static inline int env_atomic64_add_return(int i, env_atomic *a) 496 { 497 return __sync_add_and_fetch(a, i); 498 } 499 500 static inline int env_atomic64_sub_return(int i, env_atomic *a) 501 { 502 return __sync_sub_and_fetch(a, i); 503 } 504 505 static inline int env_atomic64_inc_return(env_atomic *a) 506 { 507 return env_atomic64_add_return(1, a); 508 } 509 510 static inline int env_atomic64_dec_return(env_atomic *a) 511 { 512 return env_atomic_sub_return(1, a); 513 } 514 515 static inline long env_atomic64_cmpxchg(env_atomic64 *a, long old, long new) 516 { 517 return atomic_cmpxchg(a, old, new); 518 } 519 520 /* *** COMPLETION *** */ 521 typedef struct completion { 522 sem_t sem; 523 } env_completion; 524 525 static inline void env_completion_init(env_completion *completion) 526 { 527 sem_init(&completion->sem, 0, 0); 528 } 529 530 static inline void env_completion_wait(env_completion *completion) 531 { 532 sem_wait(&completion->sem); 533 } 534 535 static inline void env_completion_complete(env_completion *completion) 536 { 537 sem_post(&completion->sem); 538 } 539 540 static inline void env_completion_destroy(env_completion *completion) 541 { 542 sem_destroy(&completion->sem); 543 } 544 545 /* *** SPIN LOCKS *** */ 546 547 typedef struct { 548 pthread_spinlock_t lock; 549 } env_spinlock; 550 551 static inline int env_spinlock_init(env_spinlock *l) 552 { 553 return pthread_spin_init(&l->lock, 0); 554 } 555 556 static inline int env_spinlock_trylock(env_spinlock *l) 557 { 558 return pthread_spin_trylock(&l->lock) ? -OCF_ERR_NO_LOCK : 0; 559 } 560 561 static inline void env_spinlock_lock(env_spinlock *l) 562 { 563 ENV_BUG_ON(pthread_spin_lock(&l->lock)); 564 } 565 566 static inline void env_spinlock_unlock(env_spinlock *l) 567 { 568 ENV_BUG_ON(pthread_spin_unlock(&l->lock)); 569 } 570 571 #define env_spinlock_lock_irqsave(l, flags) \ 572 (void)flags; \ 573 env_spinlock_lock(l) 574 575 #define env_spinlock_unlock_irqrestore(l, flags) \ 576 (void)flags; \ 577 env_spinlock_unlock(l) 578 579 static inline void env_spinlock_destroy(env_spinlock *l) 580 { 581 ENV_BUG_ON(pthread_spin_destroy(&l->lock)); 582 } 583 584 /* *** RW LOCKS *** */ 585 586 typedef struct { 587 pthread_rwlock_t lock; 588 } env_rwlock; 589 590 static inline void env_rwlock_init(env_rwlock *l) 591 { 592 ENV_BUG_ON(pthread_rwlock_init(&l->lock, NULL)); 593 } 594 595 static inline void env_rwlock_read_lock(env_rwlock *l) 596 { 597 ENV_BUG_ON(pthread_rwlock_rdlock(&l->lock)); 598 } 599 600 static inline void env_rwlock_read_unlock(env_rwlock *l) 601 { 602 ENV_BUG_ON(pthread_rwlock_unlock(&l->lock)); 603 } 604 605 static inline void env_rwlock_write_lock(env_rwlock *l) 606 { 607 ENV_BUG_ON(pthread_rwlock_wrlock(&l->lock)); 608 } 609 610 static inline void env_rwlock_write_unlock(env_rwlock *l) 611 { 612 ENV_BUG_ON(pthread_rwlock_unlock(&l->lock)); 613 } 614 615 static inline void env_rwlock_destroy(env_rwlock *l) 616 { 617 ENV_BUG_ON(pthread_rwlock_destroy(&l->lock)); 618 } 619 620 static inline void env_bit_set(int nr, volatile void *addr) 621 { 622 char *byte = (char *)addr + (nr >> 3); 623 char mask = 1 << (nr & 7); 624 625 __sync_or_and_fetch(byte, mask); 626 } 627 628 static inline void env_bit_clear(int nr, volatile void *addr) 629 { 630 char *byte = (char *)addr + (nr >> 3); 631 char mask = 1 << (nr & 7); 632 633 mask = ~mask; 634 __sync_and_and_fetch(byte, mask); 635 } 636 637 static inline bool env_bit_test(int nr, const volatile unsigned long *addr) 638 { 639 const char *byte = (char *)addr + (nr >> 3); 640 char mask = 1 << (nr & 7); 641 642 return !!(*byte & mask); 643 } 644 645 /* *** WAITQUEUE *** */ 646 647 typedef struct { 648 sem_t sem; 649 } env_waitqueue; 650 651 static inline void env_waitqueue_init(env_waitqueue *w) 652 { 653 sem_init(&w->sem, 0, 0); 654 } 655 656 static inline void env_waitqueue_wake_up(env_waitqueue *w) 657 { 658 sem_post(&w->sem); 659 } 660 661 #define env_waitqueue_wait(w, condition) \ 662 ({ \ 663 int __ret = 0; \ 664 if (!(condition)) \ 665 sem_wait(&w.sem); \ 666 __ret = __ret; \ 667 }) 668 669 /* *** SCHEDULING *** */ 670 671 /* CAS does not need this while in user-space */ 672 static inline void env_schedule(void) 673 { 674 } 675 676 #define env_cond_resched env_schedule 677 678 static inline int env_in_interrupt(void) 679 { 680 return 0; 681 } 682 683 static inline uint64_t env_get_tick_count(void) 684 { 685 return spdk_get_ticks(); 686 } 687 688 static inline uint64_t env_ticks_to_secs(uint64_t j) 689 { 690 return j / spdk_get_ticks_hz(); 691 } 692 693 static inline uint64_t env_ticks_to_msecs(uint64_t j) 694 { 695 return env_ticks_to_secs(j) * 1000; 696 } 697 698 static inline uint64_t env_ticks_to_nsecs(uint64_t j) 699 { 700 return env_ticks_to_secs(j) * 1000 * 1000; 701 } 702 703 static inline uint64_t env_ticks_to_usecs(uint64_t j) 704 { 705 return env_ticks_to_secs(j) * 1000 * 1000 * 1000; 706 } 707 708 static inline uint64_t env_secs_to_ticks(uint64_t j) 709 { 710 return j * spdk_get_ticks_hz(); 711 } 712 713 /* *** STRING OPERATIONS *** */ 714 715 /* 512 KB is sufficient amount of memory for OCF operations */ 716 #define ENV_MAX_MEM (512 * 1024) 717 718 static inline int env_memset(void *dest, size_t len, uint8_t value) 719 { 720 if (dest == NULL || len == 0) { 721 return 1; 722 } 723 724 memset(dest, value, len); 725 return 0; 726 } 727 728 static inline int env_memcpy(void *dest, size_t dmax, const void *src, size_t len) 729 { 730 if (dest == NULL || src == NULL) { 731 return 1; 732 } 733 if (dmax == 0 || dmax > ENV_MAX_MEM) { 734 return 1; 735 } 736 if (len == 0 || len > dmax) { 737 return 1; 738 } 739 740 memcpy(dest, src, len); 741 return 0; 742 } 743 744 static inline int env_memcmp(const void *aptr, size_t dmax, const void *bptr, size_t len, 745 int *diff) 746 { 747 if (diff == NULL || aptr == NULL || bptr == NULL) { 748 return 1; 749 } 750 if (dmax == 0 || dmax > ENV_MAX_MEM) { 751 return 1; 752 } 753 if (len == 0 || len > dmax) { 754 return 1; 755 } 756 757 *diff = memcmp(aptr, bptr, len); 758 return 0; 759 } 760 761 /* 4096 is sufficient max length for any OCF operation on string */ 762 #define ENV_MAX_STR (4 * 1024) 763 764 static inline size_t env_strnlen(const char *src, size_t dmax) 765 { 766 return strnlen(src, dmax); 767 } 768 769 static inline int env_strncpy(char *dest, size_t dmax, const char *src, size_t len) 770 { 771 if (dest == NULL || src == NULL) { 772 return 1; 773 } 774 if (dmax == 0 || dmax > ENV_MAX_STR) { 775 return 1; 776 } 777 if (len == 0) { 778 return 1; 779 } 780 /* Just copy as many characters as we can instead of return failure */ 781 len = min(len, dmax); 782 783 strncpy(dest, src, len); 784 return 0; 785 } 786 787 #define env_strncmp(s1, slen1, s2, slen2) strncmp(s1, s2, min(slen1, slen2)) 788 789 static inline char *env_strdup(const char *src, int flags) 790 { 791 int len; 792 char *ret; 793 794 if (src == NULL) { 795 return NULL; 796 } 797 798 len = env_strnlen(src, ENV_MAX_STR) + 1; 799 ret = env_malloc(len, flags); 800 801 if (env_strncpy(ret, ENV_MAX_STR, src, len)) { 802 return NULL; 803 } else { 804 return ret; 805 } 806 } 807 808 /* *** SORTING *** */ 809 810 static inline void env_sort(void *base, size_t num, size_t size, 811 int (*cmp_fn)(const void *, const void *), 812 void (*swap_fn)(void *, void *, int size)) 813 { 814 qsort(base, num, size, cmp_fn); 815 } 816 817 static inline void env_msleep(uint64_t n) 818 { 819 usleep(n * 1000); 820 } 821 822 static inline void env_touch_softlockup_wd(void) 823 { 824 } 825 826 /* *** CRC *** */ 827 828 uint32_t env_crc32(uint32_t crc, uint8_t const *data, size_t len); 829 830 /* EXECUTION CONTEXTS */ 831 unsigned env_get_execution_context(void); 832 void env_put_execution_context(unsigned ctx); 833 unsigned env_get_execution_context_count(void); 834 835 #endif /* __OCF_ENV_H__ */ 836