atomic.c 2.9 KB

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