1#include "test/jemalloc_test.h" 2 3#define TEST_STRUCT(p, t) \ 4struct p##_test_s { \ 5 t accum0; \ 6 t x; \ 7 t s; \ 8}; \ 9typedef 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 68TEST_STRUCT(u64, uint64_t) 69TEST_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} 77TEST_END 78 79TEST_STRUCT(u32, uint32_t) 80TEST_BEGIN(test_atomic_u32) 81{ 82 TEST_BODY(u32, uint32_t, uint32_t, u32, "#"FMTx32); 83} 84TEST_END 85 86TEST_STRUCT(p, void *) 87TEST_BEGIN(test_atomic_p) 88{ 89 TEST_BODY(p, void *, uintptr_t, ptr, "p"); 90} 91TEST_END 92 93TEST_STRUCT(zu, size_t) 94TEST_BEGIN(test_atomic_zu) 95{ 96 TEST_BODY(zu, size_t, size_t, zu, "#zx"); 97} 98TEST_END 99 100TEST_STRUCT(u, unsigned) 101TEST_BEGIN(test_atomic_u) 102{ 103 TEST_BODY(u, unsigned, unsigned, u, "#x"); 104} 105TEST_END 106 107int 108main(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