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/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 return -1; 175 } 176 177 /* *** ALLOCATOR *** */ 178 179 #define OCF_ALLOCATOR_NAME_MAX 128 180 181 typedef struct { 182 struct spdk_mempool *mempool; 183 size_t element_size; 184 } env_allocator; 185 186 env_allocator *env_allocator_create(uint32_t size, const char *name); 187 188 void env_allocator_destroy(env_allocator *allocator); 189 190 void *env_allocator_new(env_allocator *allocator); 191 192 void env_allocator_del(env_allocator *allocator, void *item); 193 194 uint32_t env_allocator_item_count(env_allocator *allocator); 195 196 /* *** MUTEX *** */ 197 198 typedef struct { 199 pthread_mutex_t m; 200 } env_mutex; 201 202 static inline int env_mutex_init(env_mutex *mutex) 203 { 204 return !!pthread_mutex_init(&mutex->m, NULL); 205 } 206 207 static inline void env_mutex_lock(env_mutex *mutex) 208 { 209 ENV_BUG_ON(pthread_mutex_lock(&mutex->m)); 210 } 211 212 static inline int env_mutex_lock_interruptible(env_mutex *mutex) 213 { 214 env_mutex_lock(mutex); 215 return 0; 216 } 217 218 static inline int env_mutex_trylock(env_mutex *mutex) 219 { 220 return pthread_mutex_trylock(&mutex->m) ? -OCF_ERR_NO_LOCK : 0; 221 } 222 223 static inline void env_mutex_unlock(env_mutex *mutex) 224 { 225 ENV_BUG_ON(pthread_mutex_unlock(&mutex->m)); 226 } 227 228 static inline int env_mutex_is_locked(env_mutex *mutex) 229 { 230 if (env_mutex_trylock(mutex) == 0) { 231 env_mutex_unlock(mutex); 232 return 0; 233 } 234 235 return 1; 236 } 237 238 static inline int env_mutex_destroy(env_mutex *mutex) 239 { 240 if (pthread_mutex_destroy(&mutex->m)) { 241 return 1; 242 } 243 244 return 0; 245 } 246 247 /* *** RECURSIVE MUTEX *** */ 248 249 typedef env_mutex env_rmutex; 250 251 static inline int env_rmutex_init(env_rmutex *rmutex) 252 { 253 pthread_mutexattr_t attr; 254 255 pthread_mutexattr_init(&attr); 256 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 257 pthread_mutex_init(&rmutex->m, &attr); 258 259 return 0; 260 } 261 262 static inline void env_rmutex_lock(env_rmutex *rmutex) 263 { 264 env_mutex_lock(rmutex); 265 } 266 267 static inline int env_rmutex_lock_interruptible(env_rmutex *rmutex) 268 { 269 return env_mutex_lock_interruptible(rmutex); 270 } 271 272 static inline int env_rmutex_trylock(env_rmutex *rmutex) 273 { 274 return env_mutex_trylock(rmutex); 275 } 276 277 static inline void env_rmutex_unlock(env_rmutex *rmutex) 278 { 279 env_mutex_unlock(rmutex); 280 } 281 282 static inline int env_rmutex_is_locked(env_rmutex *rmutex) 283 { 284 return env_mutex_is_locked(rmutex); 285 } 286 287 static inline int env_rmutex_destroy(env_rmutex *rmutex) 288 { 289 return env_mutex_destroy(rmutex); 290 } 291 292 /* *** RW SEMAPHORE *** */ 293 typedef struct { 294 pthread_rwlock_t lock; 295 } env_rwsem; 296 297 static inline int env_rwsem_init(env_rwsem *s) 298 { 299 return !!pthread_rwlock_init(&s->lock, NULL); 300 } 301 302 static inline void env_rwsem_up_read(env_rwsem *s) 303 { 304 ENV_BUG_ON(pthread_rwlock_unlock(&s->lock)); 305 } 306 307 static inline void env_rwsem_down_read(env_rwsem *s) 308 { 309 ENV_BUG_ON(pthread_rwlock_rdlock(&s->lock)); 310 } 311 312 static inline int env_rwsem_down_read_trylock(env_rwsem *s) 313 { 314 return pthread_rwlock_tryrdlock(&s->lock) ? -OCF_ERR_NO_LOCK : 0; 315 } 316 317 static inline void env_rwsem_up_write(env_rwsem *s) 318 { 319 ENV_BUG_ON(pthread_rwlock_unlock(&s->lock)); 320 } 321 322 static inline void env_rwsem_down_write(env_rwsem *s) 323 { 324 ENV_BUG_ON(pthread_rwlock_wrlock(&s->lock)); 325 } 326 327 static inline int env_rwsem_down_write_trylock(env_rwsem *s) 328 { 329 return pthread_rwlock_trywrlock(&s->lock) ? -OCF_ERR_NO_LOCK : 0; 330 } 331 332 static inline int env_rwsem_is_locked(env_rwsem *s) 333 { 334 if (env_rwsem_down_read_trylock(s) == 0) { 335 env_rwsem_up_read(s); 336 return 0; 337 } 338 339 return 1; 340 } 341 342 static inline int env_rwsem_down_read_interruptible(env_rwsem *s) 343 { 344 return pthread_rwlock_rdlock(&s->lock); 345 } 346 static inline int env_rwsem_down_write_interruptible(env_rwsem *s) 347 { 348 return pthread_rwlock_wrlock(&s->lock); 349 } 350 351 static inline int env_rwsem_destroy(env_rwsem *s) 352 { 353 return pthread_rwlock_destroy(&s->lock); 354 } 355 356 /* *** ATOMIC VARIABLES *** */ 357 358 typedef int env_atomic; 359 360 typedef long env_atomic64; 361 362 #ifndef atomic_read 363 #define atomic_read(ptr) (*(__typeof__(*ptr) *volatile) (ptr)) 364 #endif 365 366 #ifndef atomic_set 367 #define atomic_set(ptr, i) ((*(__typeof__(*ptr) *volatile) (ptr)) = (i)) 368 #endif 369 370 #define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1)) 371 #define atomic_dec(ptr) ((void) __sync_fetch_and_add(ptr, -1)) 372 #define atomic_add(ptr, n) ((void) __sync_fetch_and_add(ptr, n)) 373 #define atomic_sub(ptr, n) ((void) __sync_fetch_and_sub(ptr, n)) 374 375 #define atomic_cmpxchg __sync_val_compare_and_swap 376 377 static inline int env_atomic_read(const env_atomic *a) 378 { 379 return atomic_read(a); 380 } 381 382 static inline void env_atomic_set(env_atomic *a, int i) 383 { 384 atomic_set(a, i); 385 } 386 387 static inline void env_atomic_add(int i, env_atomic *a) 388 { 389 atomic_add(a, i); 390 } 391 392 static inline void env_atomic_sub(int i, env_atomic *a) 393 { 394 atomic_sub(a, i); 395 } 396 397 static inline bool env_atomic_sub_and_test(int i, env_atomic *a) 398 { 399 return __sync_sub_and_fetch(a, i) == 0; 400 } 401 402 static inline void env_atomic_inc(env_atomic *a) 403 { 404 atomic_inc(a); 405 } 406 407 static inline void env_atomic_dec(env_atomic *a) 408 { 409 atomic_dec(a); 410 } 411 412 static inline bool env_atomic_dec_and_test(env_atomic *a) 413 { 414 return __sync_sub_and_fetch(a, 1) == 0; 415 } 416 417 static inline bool env_atomic_inc_and_test(env_atomic *a) 418 { 419 return __sync_add_and_fetch(a, 1) == 0; 420 } 421 422 static inline int env_atomic_add_return(int i, env_atomic *a) 423 { 424 return __sync_add_and_fetch(a, i); 425 } 426 427 static inline int env_atomic_sub_return(int i, env_atomic *a) 428 { 429 return __sync_sub_and_fetch(a, i); 430 } 431 432 static inline int env_atomic_inc_return(env_atomic *a) 433 { 434 return env_atomic_add_return(1, a); 435 } 436 437 static inline int env_atomic_dec_return(env_atomic *a) 438 { 439 return env_atomic_sub_return(1, a); 440 } 441 442 static inline int env_atomic_cmpxchg(env_atomic *a, int old, int new_value) 443 { 444 return atomic_cmpxchg(a, old, new_value); 445 } 446 447 static inline int env_atomic_add_unless(env_atomic *a, int i, int u) 448 { 449 int c, old; 450 c = env_atomic_read(a); 451 for (;;) { 452 if (spdk_unlikely(c == (u))) { 453 break; 454 } 455 old = env_atomic_cmpxchg((a), c, c + (i)); 456 if (spdk_likely(old == c)) { 457 break; 458 } 459 c = old; 460 } 461 return c != (u); 462 } 463 464 static inline long env_atomic64_read(const env_atomic64 *a) 465 { 466 return atomic_read(a); 467 } 468 469 static inline void env_atomic64_set(env_atomic64 *a, long i) 470 { 471 atomic_set(a, i); 472 } 473 474 static inline void env_atomic64_add(long i, env_atomic64 *a) 475 { 476 atomic_add(a, i); 477 } 478 479 static inline void env_atomic64_sub(long i, env_atomic64 *a) 480 { 481 atomic_sub(a, i); 482 } 483 484 static inline void env_atomic64_inc(env_atomic64 *a) 485 { 486 atomic_inc(a); 487 } 488 489 static inline void env_atomic64_dec(env_atomic64 *a) 490 { 491 atomic_dec(a); 492 } 493 494 static inline int env_atomic64_add_return(int i, env_atomic *a) 495 { 496 return __sync_add_and_fetch(a, i); 497 } 498 499 static inline int env_atomic64_sub_return(int i, env_atomic *a) 500 { 501 return __sync_sub_and_fetch(a, i); 502 } 503 504 static inline int env_atomic64_inc_return(env_atomic *a) 505 { 506 return env_atomic64_add_return(1, a); 507 } 508 509 static inline int env_atomic64_dec_return(env_atomic *a) 510 { 511 return env_atomic_sub_return(1, a); 512 } 513 514 static inline long env_atomic64_cmpxchg(env_atomic64 *a, long old, long new) 515 { 516 return atomic_cmpxchg(a, old, new); 517 } 518 519 /* *** COMPLETION *** */ 520 typedef struct completion { 521 sem_t sem; 522 } env_completion; 523 524 static inline void env_completion_init(env_completion *completion) 525 { 526 sem_init(&completion->sem, 0, 0); 527 } 528 529 static inline void env_completion_wait(env_completion *completion) 530 { 531 sem_wait(&completion->sem); 532 } 533 534 static inline void env_completion_complete(env_completion *completion) 535 { 536 sem_post(&completion->sem); 537 } 538 539 static inline void env_completion_destroy(env_completion *completion) 540 { 541 sem_destroy(&completion->sem); 542 } 543 544 /* *** SPIN LOCKS *** */ 545 546 typedef struct { 547 pthread_spinlock_t lock; 548 } env_spinlock; 549 550 static inline int env_spinlock_init(env_spinlock *l) 551 { 552 return pthread_spin_init(&l->lock, 0); 553 } 554 555 static inline int env_spinlock_trylock(env_spinlock *l) 556 { 557 return pthread_spin_trylock(&l->lock) ? -OCF_ERR_NO_LOCK : 0; 558 } 559 560 static inline void env_spinlock_lock(env_spinlock *l) 561 { 562 ENV_BUG_ON(pthread_spin_lock(&l->lock)); 563 } 564 565 static inline void env_spinlock_unlock(env_spinlock *l) 566 { 567 ENV_BUG_ON(pthread_spin_unlock(&l->lock)); 568 } 569 570 #define env_spinlock_lock_irqsave(l, flags) \ 571 (void)flags; \ 572 env_spinlock_lock(l) 573 574 #define env_spinlock_unlock_irqrestore(l, flags) \ 575 (void)flags; \ 576 env_spinlock_unlock(l) 577 578 static inline void env_spinlock_destroy(env_spinlock *l) 579 { 580 ENV_BUG_ON(pthread_spin_destroy(&l->lock)); 581 } 582 583 /* *** RW LOCKS *** */ 584 585 typedef struct { 586 pthread_rwlock_t lock; 587 } env_rwlock; 588 589 static inline void env_rwlock_init(env_rwlock *l) 590 { 591 ENV_BUG_ON(pthread_rwlock_init(&l->lock, NULL)); 592 } 593 594 static inline void env_rwlock_read_lock(env_rwlock *l) 595 { 596 ENV_BUG_ON(pthread_rwlock_rdlock(&l->lock)); 597 } 598 599 static inline void env_rwlock_read_unlock(env_rwlock *l) 600 { 601 ENV_BUG_ON(pthread_rwlock_unlock(&l->lock)); 602 } 603 604 static inline void env_rwlock_write_lock(env_rwlock *l) 605 { 606 ENV_BUG_ON(pthread_rwlock_wrlock(&l->lock)); 607 } 608 609 static inline void env_rwlock_write_unlock(env_rwlock *l) 610 { 611 ENV_BUG_ON(pthread_rwlock_unlock(&l->lock)); 612 } 613 614 static inline void env_rwlock_destroy(env_rwlock *l) 615 { 616 ENV_BUG_ON(pthread_rwlock_destroy(&l->lock)); 617 } 618 619 static inline void env_bit_set(int nr, volatile void *addr) 620 { 621 char *byte = (char *)addr + (nr >> 3); 622 char mask = 1 << (nr & 7); 623 624 __sync_or_and_fetch(byte, mask); 625 } 626 627 static inline void env_bit_clear(int nr, volatile void *addr) 628 { 629 char *byte = (char *)addr + (nr >> 3); 630 char mask = 1 << (nr & 7); 631 632 __sync_and_and_fetch(byte, ~mask); 633 } 634 635 static inline bool env_bit_test(int nr, const volatile unsigned long *addr) 636 { 637 const char *byte = (char *)addr + (nr >> 3); 638 char mask = 1 << (nr & 7); 639 640 return !!(*byte & mask); 641 } 642 643 /* *** WAITQUEUE *** */ 644 645 typedef struct { 646 sem_t sem; 647 } env_waitqueue; 648 649 static inline void env_waitqueue_init(env_waitqueue *w) 650 { 651 sem_init(&w->sem, 0, 0); 652 } 653 654 static inline void env_waitqueue_wake_up(env_waitqueue *w) 655 { 656 sem_post(&w->sem); 657 } 658 659 #define env_waitqueue_wait(w, condition) \ 660 ({ \ 661 int __ret = 0; \ 662 if (!(condition)) \ 663 sem_wait(&w.sem); \ 664 __ret = __ret; \ 665 }) 666 667 /* *** SCHEDULING *** */ 668 669 /* CAS does not need this while in user-space */ 670 static inline void env_schedule(void) 671 { 672 } 673 674 #define env_cond_resched env_schedule 675 676 static inline int env_in_interrupt(void) 677 { 678 return 0; 679 } 680 681 static inline uint64_t env_get_tick_count(void) 682 { 683 return spdk_get_ticks(); 684 } 685 686 static inline uint64_t env_ticks_to_secs(uint64_t j) 687 { 688 return j / spdk_get_ticks_hz(); 689 } 690 691 static inline uint64_t env_ticks_to_msecs(uint64_t j) 692 { 693 return env_ticks_to_secs(j) * 1000; 694 } 695 696 static inline uint64_t env_ticks_to_nsecs(uint64_t j) 697 { 698 return env_ticks_to_secs(j) * 1000 * 1000; 699 } 700 701 static inline uint64_t env_ticks_to_usecs(uint64_t j) 702 { 703 return env_ticks_to_secs(j) * 1000 * 1000 * 1000; 704 } 705 706 static inline uint64_t env_secs_to_ticks(uint64_t j) 707 { 708 return j * spdk_get_ticks_hz(); 709 } 710 711 /* *** STRING OPERATIONS *** */ 712 713 /* 512 KB is sufficient amount of memory for OCF operations */ 714 #define ENV_MAX_MEM (512 * 1024) 715 716 static inline int env_memset(void *dest, size_t len, uint8_t value) 717 { 718 if (dest == NULL || len == 0) { 719 return 1; 720 } 721 722 memset(dest, value, len); 723 return 0; 724 } 725 726 static inline int env_memcpy(void *dest, size_t dmax, const void *src, size_t len) 727 { 728 if (dest == NULL || src == NULL) { 729 return 1; 730 } 731 if (dmax == 0 || dmax > ENV_MAX_MEM) { 732 return 1; 733 } 734 if (len == 0 || len > dmax) { 735 return 1; 736 } 737 738 memcpy(dest, src, len); 739 return 0; 740 } 741 742 static inline int env_memcmp(const void *aptr, size_t dmax, const void *bptr, size_t len, 743 int *diff) 744 { 745 if (diff == NULL || aptr == NULL || bptr == NULL) { 746 return 1; 747 } 748 if (dmax == 0 || dmax > ENV_MAX_MEM) { 749 return 1; 750 } 751 if (len == 0 || len > dmax) { 752 return 1; 753 } 754 755 *diff = memcmp(aptr, bptr, len); 756 return 0; 757 } 758 759 /* 4096 is sufficient max length for any OCF operation on string */ 760 #define ENV_MAX_STR (4 * 1024) 761 762 static inline size_t env_strnlen(const char *src, size_t dmax) 763 { 764 return strnlen(src, dmax); 765 } 766 767 static inline int env_strncpy(char *dest, size_t dmax, const char *src, size_t len) 768 { 769 if (dest == NULL || src == NULL) { 770 return 1; 771 } 772 if (dmax == 0 || dmax > ENV_MAX_STR) { 773 return 1; 774 } 775 if (len == 0) { 776 return 1; 777 } 778 /* Just copy as many characters as we can instead of return failure */ 779 len = min(len, dmax); 780 781 strncpy(dest, src, len); 782 return 0; 783 } 784 785 #define env_strncmp(s1, slen1, s2, slen2) strncmp(s1, s2, min(slen1, slen2)) 786 787 static inline char *env_strdup(const char *src, int flags) 788 { 789 int len; 790 char *ret; 791 792 if (src == NULL) { 793 return NULL; 794 } 795 796 len = env_strnlen(src, ENV_MAX_STR) + 1; 797 ret = env_malloc(len, flags); 798 799 if (env_strncpy(ret, ENV_MAX_STR, src, len)) { 800 return NULL; 801 } else { 802 return ret; 803 } 804 } 805 806 /* *** SORTING *** */ 807 808 static inline void env_sort(void *base, size_t num, size_t size, 809 int (*cmp_fn)(const void *, const void *), 810 void (*swap_fn)(void *, void *, int size)) 811 { 812 qsort(base, num, size, cmp_fn); 813 } 814 815 static inline void env_msleep(uint64_t n) 816 { 817 usleep(n * 1000); 818 } 819 820 static inline void env_touch_softlockup_wd(void) 821 { 822 } 823 824 /* *** CRC *** */ 825 826 uint32_t env_crc32(uint32_t crc, uint8_t const *data, size_t len); 827 828 /* EXECUTION CONTEXTS */ 829 unsigned env_get_execution_context(void); 830 void env_put_execution_context(unsigned ctx); 831 unsigned env_get_execution_context_count(void); 832 833 #endif /* __OCF_ENV_H__ */ 834