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