From: Timo Sirainen Date: Thu, 7 Dec 2017 22:54:51 +0000 (+0200) Subject: lib: timing - Allow changing sample buffer size X-Git-Tag: 2.3.0.rc1~114 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92fc2c856dcc20dd886ce79d141efd678ace595c;p=thirdparty%2Fdovecot%2Fcore.git lib: timing - Allow changing sample buffer size --- diff --git a/src/lib/timing.c b/src/lib/timing.c index 8749ea7846..60794cbe33 100644 --- a/src/lib/timing.c +++ b/src/lib/timing.c @@ -6,20 +6,32 @@ /* In order to have a vaguely accurate 95th percentile, you need way more than 20 in your subsample. */ -#define TIMING_SUBSAMPLING_BUFFER (20*24) /* 20*24 fits in a page */ +#define TIMING_DEFAULT_SUBSAMPLING_BUFFER (20*24) /* 20*24 fits in a page */ struct timing { + unsigned int sample_count; unsigned int count; bool sorted; uint64_t min; - uint64_t samples[TIMING_SUBSAMPLING_BUFFER]; uint64_t max; uint64_t sum; + uint64_t samples[]; }; struct timing *timing_init(void) { - return i_new(struct timing, 1); + return timing_init_with_size(TIMING_DEFAULT_SUBSAMPLING_BUFFER); +} + +struct timing *timing_init_with_size(unsigned int sample_count) +{ + i_assert(sample_count > 0); + + struct timing *timing = + i_malloc(sizeof(struct timing) + + sizeof(uint64_t) * sample_count); + timing->sample_count = sample_count; + return timing; } void timing_deinit(struct timing **_timing) @@ -29,18 +41,20 @@ void timing_deinit(struct timing **_timing) void timing_reset(struct timing *timing) { + unsigned int sample_count = timing->sample_count; i_zero(timing); + timing->sample_count = sample_count; } void timing_add_usecs(struct timing *timing, uint64_t usecs) { - if (timing->count < TIMING_SUBSAMPLING_BUFFER) { + if (timing->count < timing->sample_count) { timing->samples[timing->count] = usecs; if (timing->count == 0) timing->min = timing->max = usecs; } else { unsigned int idx = i_rand_limit(timing->count); - if (idx < TIMING_SUBSAMPLING_BUFFER) + if (idx < timing->sample_count) timing->samples[idx] = usecs; } @@ -86,9 +100,9 @@ static void timing_ensure_sorted(struct timing *timing) if (timing->sorted) return; - unsigned int count = (timing->count < TIMING_SUBSAMPLING_BUFFER) + unsigned int count = (timing->count < timing->sample_count) ? timing->count - : TIMING_SUBSAMPLING_BUFFER; + : timing->sample_count; i_qsort(timing->samples, count, sizeof(*timing->samples), uint64_cmp); timing->sorted = TRUE; @@ -100,9 +114,9 @@ uint64_t timing_get_median(const struct timing *timing) return 0; /* cast-away const - reading requires sorting */ timing_ensure_sorted((struct timing *)timing); - unsigned int count = (timing->count < TIMING_SUBSAMPLING_BUFFER) + unsigned int count = (timing->count < timing->sample_count) ? timing->count - : TIMING_SUBSAMPLING_BUFFER; + : timing->sample_count; unsigned int idx1 = (count-1)/2, idx2 = count/2; return (timing->samples[idx1] + timing->samples[idx2]) / 2; } @@ -113,9 +127,9 @@ uint64_t timing_get_95th(const struct timing *timing) return 0; /* cast-away const - reading requires sorting */ timing_ensure_sorted((struct timing *)timing); - unsigned int count = (timing->count < TIMING_SUBSAMPLING_BUFFER) + unsigned int count = (timing->count < timing->sample_count) ? timing->count - : TIMING_SUBSAMPLING_BUFFER; + : timing->sample_count; unsigned int idx = count - count/20 - 1; return timing->samples[idx]; } diff --git a/src/lib/timing.h b/src/lib/timing.h index 79536f9ed1..0d016b5b0e 100644 --- a/src/lib/timing.h +++ b/src/lib/timing.h @@ -2,6 +2,7 @@ #define TIMING_H struct timing *timing_init(void); +struct timing *timing_init_with_size(unsigned int sample_count); void timing_deinit(struct timing **timing); /* Reset all events. */