1a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans#include "test/jemalloc_test.h"
2a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
3a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans#define	TEST_STRUCT(p, t)						\
4a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evansstruct p##_test_s {							\
5a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	t	accum0;							\
6a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	t	x;							\
783e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris	t	s;							\
8a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans};									\
9a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evanstypedef struct p##_test_s p##_test_t;
10a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
1183e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris#define	TEST_BODY(p, t, tc, ta, PRI) do {				\
12a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	const p##_test_t tests[] = {					\
1383e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t)-1, (t)-1, (t)-2},					\
1483e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t)-1, (t) 0, (t)-2},					\
1583e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t)-1, (t) 1, (t)-2},					\
16a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans									\
1783e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t) 0, (t)-1, (t)-2},					\
1883e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t) 0, (t) 0, (t)-2},					\
1983e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t) 0, (t) 1, (t)-2},					\
20a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans									\
2183e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t) 1, (t)-1, (t)-2},					\
2283e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t) 1, (t) 0, (t)-2},					\
2383e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t) 1, (t) 1, (t)-2},					\
24a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans									\
2583e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t)0, (t)-(1 << 22), (t)-2},				\
2683e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t)0, (t)(1 << 22), (t)-2},				\
2783e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t)(1 << 22), (t)-(1 << 22), (t)-2},			\
2883e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		{(t)(1 << 22), (t)(1 << 22), (t)-2}			\
29a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	};								\
30a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	unsigned i;							\
31a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans									\
32a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	for (i = 0; i < sizeof(tests)/sizeof(p##_test_t); i++) {	\
3383e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		bool err;						\
34a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans		t accum = tests[i].accum0;				\
3583e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		assert_##ta##_eq(atomic_read_##p(&accum),		\
3683e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    tests[i].accum0,					\
3783e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    "Erroneous read, i=%u", i);				\
3883e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris									\
3983e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		assert_##ta##_eq(atomic_add_##p(&accum, tests[i].x),	\
4083e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    (t)((tc)tests[i].accum0 + (tc)tests[i].x),		\
4183e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    "i=%u, accum=%"PRI", x=%"PRI,			\
42a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans		    i, tests[i].accum0, tests[i].x);			\
4383e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		assert_##ta##_eq(atomic_read_##p(&accum), accum,	\
4483e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    "Erroneous add, i=%u", i);				\
45a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans									\
46a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans		accum = tests[i].accum0;				\
4783e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		assert_##ta##_eq(atomic_sub_##p(&accum, tests[i].x),	\
4883e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    (t)((tc)tests[i].accum0 - (tc)tests[i].x),		\
4983e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    "i=%u, accum=%"PRI", x=%"PRI,			\
50a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans		    i, tests[i].accum0, tests[i].x);			\
5183e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		assert_##ta##_eq(atomic_read_##p(&accum), accum,	\
5283e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    "Erroneous sub, i=%u", i);				\
5383e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris									\
5483e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		accum = tests[i].accum0;				\
5583e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		err = atomic_cas_##p(&accum, tests[i].x, tests[i].s);	\
5683e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		assert_b_eq(err, tests[i].accum0 != tests[i].x,		\
5783e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    "Erroneous cas success/failure result");		\
5883e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		assert_##ta##_eq(accum, err ? tests[i].accum0 :		\
5983e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    tests[i].s, "Erroneous cas effect, i=%u", i);	\
6083e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris									\
6183e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		accum = tests[i].accum0;				\
6283e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		atomic_write_##p(&accum, tests[i].s);			\
6383e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		assert_##ta##_eq(accum, tests[i].s,			\
6483e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris		    "Erroneous write, i=%u", i);			\
65a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	}								\
66a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans} while (0)
67a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
68a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_STRUCT(uint64, uint64_t)
69a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_BEGIN(test_atomic_uint64)
70a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans{
71a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
72a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans#if !(LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3)
73a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	test_skip("64-bit atomic operations not supported");
74a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans#else
7583e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris	TEST_BODY(uint64, uint64_t, uint64_t, u64, PRIx64);
76a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans#endif
77a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans}
78a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_END
79a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
80a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_STRUCT(uint32, uint32_t)
81a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_BEGIN(test_atomic_uint32)
82a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans{
83a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
8483e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris	TEST_BODY(uint32, uint32_t, uint32_t, u32, "#"PRIx32);
8583e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris}
8683e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher FerrisTEST_END
8783e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris
8883e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher FerrisTEST_STRUCT(p, void *)
8983e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher FerrisTEST_BEGIN(test_atomic_p)
9083e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris{
9183e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris
9283e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris	TEST_BODY(p, void *, uintptr_t, ptr, "p");
93a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans}
94a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_END
95a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
96a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_STRUCT(z, size_t)
97a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_BEGIN(test_atomic_z)
98a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans{
99a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
10083e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris	TEST_BODY(z, size_t, size_t, zu, "#zx");
101a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans}
102a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_END
103a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
104a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_STRUCT(u, unsigned)
105a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_BEGIN(test_atomic_u)
106a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans{
107a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
10883e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris	TEST_BODY(u, unsigned, unsigned, u, "#x");
109a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans}
110a2ea54c98640eafc5bb256fa4369d5553499ac81Jason EvansTEST_END
111a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
112a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evansint
113a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evansmain(void)
114a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans{
115a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans
116a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	return (test(
117a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	    test_atomic_uint64,
118a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	    test_atomic_uint32,
11983e5767ee9a8c68150cca06ae0d27a13ba4fcaf8Christopher Ferris	    test_atomic_p,
120a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	    test_atomic_z,
121a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans	    test_atomic_u));
122a2ea54c98640eafc5bb256fa4369d5553499ac81Jason Evans}
123