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(u64,uint64_t)68 TEST_STRUCT(u64, uint64_t)
69 TEST_BEGIN(test_atomic_u64)
70 {
71 #if !(LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3)
72 test_skip("64-bit atomic operations not supported");
73 #else
74 TEST_BODY(u64, uint64_t, uint64_t, u64, FMTx64);
75 #endif
76 }
77 TEST_END
78
TEST_STRUCT(u32,uint32_t)79 TEST_STRUCT(u32, uint32_t)
80 TEST_BEGIN(test_atomic_u32)
81 {
82 TEST_BODY(u32, uint32_t, uint32_t, u32, "#"FMTx32);
83 }
84 TEST_END
85
TEST_STRUCT(p,void *)86 TEST_STRUCT(p, void *)
87 TEST_BEGIN(test_atomic_p)
88 {
89 TEST_BODY(p, void *, uintptr_t, ptr, "p");
90 }
91 TEST_END
92
TEST_STRUCT(zu,size_t)93 TEST_STRUCT(zu, size_t)
94 TEST_BEGIN(test_atomic_zu)
95 {
96 TEST_BODY(zu, size_t, size_t, zu, "#zx");
97 }
98 TEST_END
99
TEST_STRUCT(u,unsigned)100 TEST_STRUCT(u, unsigned)
101 TEST_BEGIN(test_atomic_u)
102 {
103 TEST_BODY(u, unsigned, unsigned, u, "#x");
104 }
105 TEST_END
106
107 int
main(void)108 main(void)
109 {
110 return (test(
111 test_atomic_u64,
112 test_atomic_u32,
113 test_atomic_p,
114 test_atomic_zu,
115 test_atomic_u));
116 }
117