diff options
Diffstat (limited to 'lib/atomic64_test.c')
-rw-r--r-- | lib/atomic64_test.c | 120 |
1 files changed, 79 insertions, 41 deletions
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c index 83c33a5bcffb..18e422b259cf 100644 --- a/lib/atomic64_test.c +++ b/lib/atomic64_test.c | |||
@@ -27,6 +27,65 @@ do { \ | |||
27 | (unsigned long long)r); \ | 27 | (unsigned long long)r); \ |
28 | } while (0) | 28 | } while (0) |
29 | 29 | ||
30 | /* | ||
31 | * Test for a atomic operation family, | ||
32 | * @test should be a macro accepting parameters (bit, op, ...) | ||
33 | */ | ||
34 | |||
35 | #define FAMILY_TEST(test, bit, op, args...) \ | ||
36 | do { \ | ||
37 | test(bit, op, ##args); \ | ||
38 | test(bit, op##_acquire, ##args); \ | ||
39 | test(bit, op##_release, ##args); \ | ||
40 | test(bit, op##_relaxed, ##args); \ | ||
41 | } while (0) | ||
42 | |||
43 | #define TEST_RETURN(bit, op, c_op, val) \ | ||
44 | do { \ | ||
45 | atomic##bit##_set(&v, v0); \ | ||
46 | r = v0; \ | ||
47 | r c_op val; \ | ||
48 | BUG_ON(atomic##bit##_##op(val, &v) != r); \ | ||
49 | BUG_ON(atomic##bit##_read(&v) != r); \ | ||
50 | } while (0) | ||
51 | |||
52 | #define RETURN_FAMILY_TEST(bit, op, c_op, val) \ | ||
53 | do { \ | ||
54 | FAMILY_TEST(TEST_RETURN, bit, op, c_op, val); \ | ||
55 | } while (0) | ||
56 | |||
57 | #define TEST_ARGS(bit, op, init, ret, expect, args...) \ | ||
58 | do { \ | ||
59 | atomic##bit##_set(&v, init); \ | ||
60 | BUG_ON(atomic##bit##_##op(&v, ##args) != ret); \ | ||
61 | BUG_ON(atomic##bit##_read(&v) != expect); \ | ||
62 | } while (0) | ||
63 | |||
64 | #define XCHG_FAMILY_TEST(bit, init, new) \ | ||
65 | do { \ | ||
66 | FAMILY_TEST(TEST_ARGS, bit, xchg, init, init, new, new); \ | ||
67 | } while (0) | ||
68 | |||
69 | #define CMPXCHG_FAMILY_TEST(bit, init, new, wrong) \ | ||
70 | do { \ | ||
71 | FAMILY_TEST(TEST_ARGS, bit, cmpxchg, \ | ||
72 | init, init, new, init, new); \ | ||
73 | FAMILY_TEST(TEST_ARGS, bit, cmpxchg, \ | ||
74 | init, init, init, wrong, new); \ | ||
75 | } while (0) | ||
76 | |||
77 | #define INC_RETURN_FAMILY_TEST(bit, i) \ | ||
78 | do { \ | ||
79 | FAMILY_TEST(TEST_ARGS, bit, inc_return, \ | ||
80 | i, (i) + one, (i) + one); \ | ||
81 | } while (0) | ||
82 | |||
83 | #define DEC_RETURN_FAMILY_TEST(bit, i) \ | ||
84 | do { \ | ||
85 | FAMILY_TEST(TEST_ARGS, bit, dec_return, \ | ||
86 | i, (i) - one, (i) - one); \ | ||
87 | } while (0) | ||
88 | |||
30 | static __init void test_atomic(void) | 89 | static __init void test_atomic(void) |
31 | { | 90 | { |
32 | int v0 = 0xaaa31337; | 91 | int v0 = 0xaaa31337; |
@@ -45,6 +104,18 @@ static __init void test_atomic(void) | |||
45 | TEST(, and, &=, v1); | 104 | TEST(, and, &=, v1); |
46 | TEST(, xor, ^=, v1); | 105 | TEST(, xor, ^=, v1); |
47 | TEST(, andnot, &= ~, v1); | 106 | TEST(, andnot, &= ~, v1); |
107 | |||
108 | RETURN_FAMILY_TEST(, add_return, +=, onestwos); | ||
109 | RETURN_FAMILY_TEST(, add_return, +=, -one); | ||
110 | RETURN_FAMILY_TEST(, sub_return, -=, onestwos); | ||
111 | RETURN_FAMILY_TEST(, sub_return, -=, -one); | ||
112 | |||
113 | INC_RETURN_FAMILY_TEST(, v0); | ||
114 | DEC_RETURN_FAMILY_TEST(, v0); | ||
115 | |||
116 | XCHG_FAMILY_TEST(, v0, v1); | ||
117 | CMPXCHG_FAMILY_TEST(, v0, v1, onestwos); | ||
118 | |||
48 | } | 119 | } |
49 | 120 | ||
50 | #define INIT(c) do { atomic64_set(&v, c); r = c; } while (0) | 121 | #define INIT(c) do { atomic64_set(&v, c); r = c; } while (0) |
@@ -74,25 +145,10 @@ static __init void test_atomic64(void) | |||
74 | TEST(64, xor, ^=, v1); | 145 | TEST(64, xor, ^=, v1); |
75 | TEST(64, andnot, &= ~, v1); | 146 | TEST(64, andnot, &= ~, v1); |
76 | 147 | ||
77 | INIT(v0); | 148 | RETURN_FAMILY_TEST(64, add_return, +=, onestwos); |
78 | r += onestwos; | 149 | RETURN_FAMILY_TEST(64, add_return, +=, -one); |
79 | BUG_ON(atomic64_add_return(onestwos, &v) != r); | 150 | RETURN_FAMILY_TEST(64, sub_return, -=, onestwos); |
80 | BUG_ON(v.counter != r); | 151 | RETURN_FAMILY_TEST(64, sub_return, -=, -one); |
81 | |||
82 | INIT(v0); | ||
83 | r += -one; | ||
84 | BUG_ON(atomic64_add_return(-one, &v) != r); | ||
85 | BUG_ON(v.counter != r); | ||
86 | |||
87 | INIT(v0); | ||
88 | r -= onestwos; | ||
89 | BUG_ON(atomic64_sub_return(onestwos, &v) != r); | ||
90 | BUG_ON(v.counter != r); | ||
91 | |||
92 | INIT(v0); | ||
93 | r -= -one; | ||
94 | BUG_ON(atomic64_sub_return(-one, &v) != r); | ||
95 | BUG_ON(v.counter != r); | ||
96 | 152 | ||
97 | INIT(v0); | 153 | INIT(v0); |
98 | atomic64_inc(&v); | 154 | atomic64_inc(&v); |
@@ -100,33 +156,15 @@ static __init void test_atomic64(void) | |||
100 | BUG_ON(v.counter != r); | 156 | BUG_ON(v.counter != r); |
101 | 157 | ||
102 | INIT(v0); | 158 | INIT(v0); |
103 | r += one; | ||
104 | BUG_ON(atomic64_inc_return(&v) != r); | ||
105 | BUG_ON(v.counter != r); | ||
106 | |||
107 | INIT(v0); | ||
108 | atomic64_dec(&v); | 159 | atomic64_dec(&v); |
109 | r -= one; | 160 | r -= one; |
110 | BUG_ON(v.counter != r); | 161 | BUG_ON(v.counter != r); |
111 | 162 | ||
112 | INIT(v0); | 163 | INC_RETURN_FAMILY_TEST(64, v0); |
113 | r -= one; | 164 | DEC_RETURN_FAMILY_TEST(64, v0); |
114 | BUG_ON(atomic64_dec_return(&v) != r); | ||
115 | BUG_ON(v.counter != r); | ||
116 | |||
117 | INIT(v0); | ||
118 | BUG_ON(atomic64_xchg(&v, v1) != v0); | ||
119 | r = v1; | ||
120 | BUG_ON(v.counter != r); | ||
121 | |||
122 | INIT(v0); | ||
123 | BUG_ON(atomic64_cmpxchg(&v, v0, v1) != v0); | ||
124 | r = v1; | ||
125 | BUG_ON(v.counter != r); | ||
126 | 165 | ||
127 | INIT(v0); | 166 | XCHG_FAMILY_TEST(64, v0, v1); |
128 | BUG_ON(atomic64_cmpxchg(&v, v2, v1) != v0); | 167 | CMPXCHG_FAMILY_TEST(64, v0, v1, v2); |
129 | BUG_ON(v.counter != r); | ||
130 | 168 | ||
131 | INIT(v0); | 169 | INIT(v0); |
132 | BUG_ON(atomic64_add_unless(&v, one, v0)); | 170 | BUG_ON(atomic64_add_unless(&v, one, v0)); |