xref: /netbsd-src/external/bsd/jemalloc/dist/test/unit/seq.c (revision 7bdf38e5b7a28439665f2fdeff81e36913eef7dd)
1*7bdf38e5Schristos #include "test/jemalloc_test.h"
2*7bdf38e5Schristos 
3*7bdf38e5Schristos #include "jemalloc/internal/seq.h"
4*7bdf38e5Schristos 
5*7bdf38e5Schristos typedef struct data_s data_t;
6*7bdf38e5Schristos struct data_s {
7*7bdf38e5Schristos 	int arr[10];
8*7bdf38e5Schristos };
9*7bdf38e5Schristos 
10*7bdf38e5Schristos static void
11*7bdf38e5Schristos set_data(data_t *data, int num) {
12*7bdf38e5Schristos 	for (int i = 0; i < 10; i++) {
13*7bdf38e5Schristos 		data->arr[i] = num;
14*7bdf38e5Schristos 	}
15*7bdf38e5Schristos }
16*7bdf38e5Schristos 
17*7bdf38e5Schristos static void
18*7bdf38e5Schristos expect_data(data_t *data) {
19*7bdf38e5Schristos 	int num = data->arr[0];
20*7bdf38e5Schristos 	for (int i = 0; i < 10; i++) {
21*7bdf38e5Schristos 		expect_d_eq(num, data->arr[i], "Data consistency error");
22*7bdf38e5Schristos 	}
23*7bdf38e5Schristos }
24*7bdf38e5Schristos 
25*7bdf38e5Schristos seq_define(data_t, data)
26*7bdf38e5Schristos 
27*7bdf38e5Schristos typedef struct thd_data_s thd_data_t;
28*7bdf38e5Schristos struct thd_data_s {
29*7bdf38e5Schristos 	seq_data_t data;
30*7bdf38e5Schristos };
31*7bdf38e5Schristos 
32*7bdf38e5Schristos static void *
33*7bdf38e5Schristos seq_reader_thd(void *arg) {
34*7bdf38e5Schristos 	thd_data_t *thd_data = (thd_data_t *)arg;
35*7bdf38e5Schristos 	int iter = 0;
36*7bdf38e5Schristos 	data_t local_data;
37*7bdf38e5Schristos 	while (iter < 1000 * 1000 - 1) {
38*7bdf38e5Schristos 		bool success = seq_try_load_data(&local_data, &thd_data->data);
39*7bdf38e5Schristos 		if (success) {
40*7bdf38e5Schristos 			expect_data(&local_data);
41*7bdf38e5Schristos 			expect_d_le(iter, local_data.arr[0],
42*7bdf38e5Schristos 			    "Seq read went back in time.");
43*7bdf38e5Schristos 			iter = local_data.arr[0];
44*7bdf38e5Schristos 		}
45*7bdf38e5Schristos 	}
46*7bdf38e5Schristos 	return NULL;
47*7bdf38e5Schristos }
48*7bdf38e5Schristos 
49*7bdf38e5Schristos static void *
50*7bdf38e5Schristos seq_writer_thd(void *arg) {
51*7bdf38e5Schristos 	thd_data_t *thd_data = (thd_data_t *)arg;
52*7bdf38e5Schristos 	data_t local_data;
53*7bdf38e5Schristos 	memset(&local_data, 0, sizeof(local_data));
54*7bdf38e5Schristos 	for (int i = 0; i < 1000 * 1000; i++) {
55*7bdf38e5Schristos 		set_data(&local_data, i);
56*7bdf38e5Schristos 		seq_store_data(&thd_data->data, &local_data);
57*7bdf38e5Schristos 	}
58*7bdf38e5Schristos 	return NULL;
59*7bdf38e5Schristos }
60*7bdf38e5Schristos 
61*7bdf38e5Schristos TEST_BEGIN(test_seq_threaded) {
62*7bdf38e5Schristos 	thd_data_t thd_data;
63*7bdf38e5Schristos 	memset(&thd_data, 0, sizeof(thd_data));
64*7bdf38e5Schristos 
65*7bdf38e5Schristos 	thd_t reader;
66*7bdf38e5Schristos 	thd_t writer;
67*7bdf38e5Schristos 
68*7bdf38e5Schristos 	thd_create(&reader, seq_reader_thd, &thd_data);
69*7bdf38e5Schristos 	thd_create(&writer, seq_writer_thd, &thd_data);
70*7bdf38e5Schristos 
71*7bdf38e5Schristos 	thd_join(reader, NULL);
72*7bdf38e5Schristos 	thd_join(writer, NULL);
73*7bdf38e5Schristos }
74*7bdf38e5Schristos TEST_END
75*7bdf38e5Schristos 
76*7bdf38e5Schristos TEST_BEGIN(test_seq_simple) {
77*7bdf38e5Schristos 	data_t data;
78*7bdf38e5Schristos 	seq_data_t seq;
79*7bdf38e5Schristos 	memset(&seq, 0, sizeof(seq));
80*7bdf38e5Schristos 	for (int i = 0; i < 1000 * 1000; i++) {
81*7bdf38e5Schristos 		set_data(&data, i);
82*7bdf38e5Schristos 		seq_store_data(&seq, &data);
83*7bdf38e5Schristos 		set_data(&data, 0);
84*7bdf38e5Schristos 		bool success = seq_try_load_data(&data, &seq);
85*7bdf38e5Schristos 		expect_b_eq(success, true, "Failed non-racing read");
86*7bdf38e5Schristos 		expect_data(&data);
87*7bdf38e5Schristos 	}
88*7bdf38e5Schristos }
89*7bdf38e5Schristos TEST_END
90*7bdf38e5Schristos 
91*7bdf38e5Schristos int main(void) {
92*7bdf38e5Schristos 	return test_no_reentrancy(
93*7bdf38e5Schristos 	    test_seq_simple,
94*7bdf38e5Schristos 	    test_seq_threaded);
95*7bdf38e5Schristos }
96