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