Home | History | Annotate | Line # | Download | only in unit
      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