• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2016 Cyril Hrubis <chrubis@suse.cz>
4  * Copyright (c) 2013 Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
5  * Copyright (c) 2010 Ngie Cooper <yaneurabeya@gmail.com>
6  * Copyright (c) 2008 Mike Frysinger <vapier@gmail.com>
7  */
8 
9 #ifndef TST_COMMON_H__
10 #define TST_COMMON_H__
11 
12 #define LTP_ATTRIBUTE_NORETURN		__attribute__((noreturn))
13 #define LTP_ATTRIBUTE_UNUSED		__attribute__((unused))
14 #define LTP_ATTRIBUTE_UNUSED_RESULT	__attribute__((warn_unused_result))
15 
16 #ifndef ARRAY_SIZE
17 # define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
18 #endif
19 
20 /* Round x to the next multiple of a.
21  * a should be a power of 2.
22  */
23 #define LTP_ALIGN(x, a)    __LTP_ALIGN_MASK(x, (typeof(x))(a) - 1)
24 #define __LTP_ALIGN_MASK(x, mask)  (((x) + (mask)) & ~(mask))
25 
26 /**
27  * TST_RETRY_FUNC() - Repeatedly retry a function with an increasing delay.
28  * @FUNC - The function which will be retried
29  * @ECHCK - Function/macro for validating @FUNC return value
30  *
31  * This macro will call @FUNC in a loop with a delay between retries.
32  * If ECHCK(ret) evaluates to non-zero, the loop ends. The delay between
33  * retries starts at one microsecond and is then doubled each iteration until
34  * it exceeds one second (the total time sleeping will be approximately one
35  * second as well). When the delay exceeds one second, the loop will end.
36  * The TST_RETRY_FUNC() macro returns the last value returned by @FUNC.
37  */
38 #define TST_RETRY_FUNC(FUNC, ECHCK) \
39 	TST_RETRY_FN_EXP_BACKOFF(FUNC, ECHCK, 1)
40 
41 #define TST_RETRY_FN_EXP_BACKOFF(FUNC, ECHCK, MAX_DELAY)	\
42 ({	unsigned int tst_delay_, tst_max_delay_;			\
43 	typeof(FUNC) tst_ret_;						\
44 	tst_delay_ = 1;							\
45 	tst_max_delay_ = tst_multiply_timeout(MAX_DELAY * 1000000);	\
46 	for (;;) {							\
47 		errno = 0;						\
48 		tst_ret_ = FUNC;					\
49 		if (ECHCK(tst_ret_))					\
50 			break;						\
51 		if (tst_delay_ < tst_max_delay_) {			\
52 			usleep(tst_delay_);				\
53 			tst_delay_ *= 2;				\
54 		} else {						\
55 			break;						\
56 		}							\
57 	}								\
58 	tst_ret_;							\
59 })
60 
61 /*
62  * Return value validation macros for TST_RETRY_FUNC():
63  * TST_RETVAL_EQ0() - Check that value is equal to zero
64  */
65 #define TST_RETVAL_EQ0(x) (!(x))
66 
67 /*
68  * TST_RETVAL_NOTNULL() - Check that value is not equal to zero/NULL
69  */
70 #define TST_RETVAL_NOTNULL(x) (!!(x))
71 
72 /*
73  * TST_RETVAL_GE0() - Check that value is greater than or equal to zero
74  */
75 #define TST_RETVAL_GE0(x) ((x) >= 0)
76 
77 #define TST_BUILD_BUG_ON(condition) \
78 	do { ((void)sizeof(char[1 - 2 * !!(condition)])); } while (0)
79 
80 #define TST_BRK_SUPPORTS_ONLY_TCONF_TBROK(condition) \
81 	TST_BUILD_BUG_ON(condition)
82 
83 #define TST_RES_SUPPORTS_TCONF_TFAIL_TINFO_TPASS_TWARN(condition) \
84 	TST_BUILD_BUG_ON(condition)
85 
86 #endif /* TST_COMMON_H__ */
87