xref: /netbsd-src/external/bsd/jemalloc/dist/test/unit/counter.c (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
1 #include "test/jemalloc_test.h"
2 
3 static const uint64_t interval = 1 << 20;
4 
5 TEST_BEGIN(test_counter_accum) {
6 	uint64_t increment = interval >> 4;
7 	unsigned n = interval / increment;
8 	uint64_t accum = 0;
9 
10 	counter_accum_t c;
11 	counter_accum_init(&c, interval);
12 
13 	tsd_t *tsd = tsd_fetch();
14 	bool trigger;
15 	for (unsigned i = 0; i < n; i++) {
16 		trigger = counter_accum(tsd_tsdn(tsd), &c, increment);
17 		accum += increment;
18 		if (accum < interval) {
19 			expect_b_eq(trigger, false, "Should not trigger");
20 		} else {
21 			expect_b_eq(trigger, true, "Should have triggered");
22 		}
23 	}
24 	expect_b_eq(trigger, true, "Should have triggered");
25 }
26 TEST_END
27 
28 void
29 expect_counter_value(counter_accum_t *c, uint64_t v) {
30 	uint64_t accum = locked_read_u64_unsynchronized(&c->accumbytes);
31 	expect_u64_eq(accum, v, "Counter value mismatch");
32 }
33 
34 #define N_THDS (16)
35 #define N_ITER_THD (1 << 12)
36 #define ITER_INCREMENT (interval >> 4)
37 
38 static void *
39 thd_start(void *varg) {
40 	counter_accum_t *c = (counter_accum_t *)varg;
41 
42 	tsd_t *tsd = tsd_fetch();
43 	bool trigger;
44 	uintptr_t n_triggered = 0;
45 	for (unsigned i = 0; i < N_ITER_THD; i++) {
46 		trigger = counter_accum(tsd_tsdn(tsd), c, ITER_INCREMENT);
47 		n_triggered += trigger ? 1 : 0;
48 	}
49 
50 	return (void *)n_triggered;
51 }
52 
53 
54 TEST_BEGIN(test_counter_mt) {
55 	counter_accum_t shared_c;
56 	counter_accum_init(&shared_c, interval);
57 
58 	thd_t thds[N_THDS];
59 	unsigned i;
60 	for (i = 0; i < N_THDS; i++) {
61 		thd_create(&thds[i], thd_start, (void *)&shared_c);
62 	}
63 
64 	uint64_t sum = 0;
65 	for (i = 0; i < N_THDS; i++) {
66 		void *ret;
67 		thd_join(thds[i], &ret);
68 		sum += (uintptr_t)ret;
69 	}
70 	expect_u64_eq(sum, N_THDS * N_ITER_THD / (interval / ITER_INCREMENT),
71 	    "Incorrect number of triggers");
72 }
73 TEST_END
74 
75 int
76 main(void) {
77 	return test(
78 	    test_counter_accum,
79 	    test_counter_mt);
80 }
81