xref: /third_party/ltp/include/tst_common.h (revision f08c3bdf)
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/* stringification */
87#define TST_TO_STR_(s) #s
88#define TST_TO_STR(s) TST_TO_STR_(s)
89
90#endif /* TST_COMMON_H__ */
91