xref: /spdk/lib/env_ocf/ocf_env.h (revision b30d57cdad6d2bc75cc1e4e2ebbcebcb0d98dcfa)
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