1 #include "test/jemalloc_test.h"
2
3 #define TEST_STRUCT(p, t) \
4 struct p##_test_s { \
5 t accum0; \
6 t x; \
7 t s; \
8 }; \
9 typedef struct p##_test_s p##_test_t;
10
11 #define TEST_BODY(p, t, tc, ta, FMT) do { \
12 const p##_test_t tests[] = { \
13 {(t)-1, (t)-1, (t)-2}, \
14 {(t)-1, (t) 0, (t)-2}, \
15 {(t)-1, (t) 1, (t)-2}, \
16 \
17 {(t) 0, (t)-1, (t)-2}, \
18 {(t) 0, (t) 0, (t)-2}, \
19 {(t) 0, (t) 1, (t)-2}, \
20 \
21 {(t) 1, (t)-1, (t)-2}, \
22 {(t) 1, (t) 0, (t)-2}, \
23 {(t) 1, (t) 1, (t)-2}, \
24 \
25 {(t)0, (t)-(1 << 22), (t)-2}, \
26 {(t)0, (t)(1 << 22), (t)-2}, \
27 {(t)(1 << 22), (t)-(1 << 22), (t)-2}, \
28 {(t)(1 << 22), (t)(1 << 22), (t)-2} \
29 }; \
30 unsigned i; \
31 \
32 for (i = 0; i < sizeof(tests)/sizeof(p##_test_t); i++) { \
33 bool err; \
34 t accum = tests[i].accum0; \
35 assert_##ta##_eq(atomic_read_##p(&accum), \
36 tests[i].accum0, \
37 "Erroneous read, i=%u", i); \
38 \
39 assert_##ta##_eq(atomic_add_##p(&accum, tests[i].x), \
40 (t)((tc)tests[i].accum0 + (tc)tests[i].x), \
41 "i=%u, accum=%"FMT", x=%"FMT, \
42 i, tests[i].accum0, tests[i].x); \
43 assert_##ta##_eq(atomic_read_##p(&accum), accum, \
44 "Erroneous add, i=%u", i); \
45 \
46 accum = tests[i].accum0; \
47 assert_##ta##_eq(atomic_sub_##p(&accum, tests[i].x), \
48 (t)((tc)tests[i].accum0 - (tc)tests[i].x), \
49 "i=%u, accum=%"FMT", x=%"FMT, \
50 i, tests[i].accum0, tests[i].x); \
51 assert_##ta##_eq(atomic_read_##p(&accum), accum, \
52 "Erroneous sub, i=%u", i); \
53 \
54 accum = tests[i].accum0; \
55 err = atomic_cas_##p(&accum, tests[i].x, tests[i].s); \
56 assert_b_eq(err, tests[i].accum0 != tests[i].x, \
57 "Erroneous cas success/failure result"); \
58 assert_##ta##_eq(accum, err ? tests[i].accum0 : \
59 tests[i].s, "Erroneous cas effect, i=%u", i); \
60 \
61 accum = tests[i].accum0; \
62 atomic_write_##p(&accum, tests[i].s); \
63 assert_##ta##_eq(accum, tests[i].s, \
64 "Erroneous write, i=%u", i); \
65 } \
66 } while (0)
67
TEST_STRUCT(uint64,uint64_t)68 TEST_STRUCT(uint64, uint64_t)
69 TEST_BEGIN(test_atomic_uint64)
70 {
71
72 #if !(LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3)
73 test_skip("64-bit atomic operations not supported");
74 #else
75 TEST_BODY(uint64, uint64_t, uint64_t, u64, FMTx64);
76 #endif
77 }
78 TEST_END
79
TEST_STRUCT(uint32,uint32_t)80 TEST_STRUCT(uint32, uint32_t)
81 TEST_BEGIN(test_atomic_uint32)
82 {
83
84 TEST_BODY(uint32, uint32_t, uint32_t, u32, "#"FMTx32);
85 }
86 TEST_END
87
TEST_STRUCT(p,void *)88 TEST_STRUCT(p, void *)
89 TEST_BEGIN(test_atomic_p)
90 {
91
92 TEST_BODY(p, void *, uintptr_t, ptr, "p");
93 }
94 TEST_END
95
TEST_STRUCT(z,size_t)96 TEST_STRUCT(z, size_t)
97 TEST_BEGIN(test_atomic_z)
98 {
99
100 TEST_BODY(z, size_t, size_t, zu, "#zx");
101 }
102 TEST_END
103
TEST_STRUCT(u,unsigned)104 TEST_STRUCT(u, unsigned)
105 TEST_BEGIN(test_atomic_u)
106 {
107
108 TEST_BODY(u, unsigned, unsigned, u, "#x");
109 }
110 TEST_END
111
112 int
main(void)113 main(void)
114 {
115
116 return (test(
117 test_atomic_uint64,
118 test_atomic_uint32,
119 test_atomic_p,
120 test_atomic_z,
121 test_atomic_u));
122 }
123