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 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 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 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 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 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 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