summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDamien Lespiau <damien.lespiau@intel.com>2015-06-27 17:34:51 +0100
committerDamien Lespiau <damien.lespiau@intel.com>2015-06-27 19:05:41 +0100
commit00432ff260beba0bf6535d7fd1c0275de303ed57 (patch)
treeabf1a24eadeaa6d4819c80fb3591741b080c0fd2 /lib
parent817ea87b6edab2d25a2994f076562ee03aa91fc6 (diff)
stats: Allow the underlying arrays to grow at will
Chris mentioned he wanted to be able to measure a variable "for one second" and use igt_stats to store them. That's one case where we don't know the number of data points upfront. We should really support that, so here it is. v2: Just free ->sorted when a new capacity is needed. ensure_sorted_values() will then reallocate the array to the new capacity on demand (Chris) Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/igt_stats.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/lib/igt_stats.c b/lib/igt_stats.c
index caf3f374..665f1c99 100644
--- a/lib/igt_stats.c
+++ b/lib/igt_stats.c
@@ -63,6 +63,37 @@
* ]|
*/
+static unsigned int get_new_capacity(int need)
+{
+ unsigned int new_capacity;
+
+ /* taken from Python's list */
+ new_capacity = (need >> 6) + (need < 9 ? 3 : 6);
+ new_capacity += need;
+
+ return new_capacity;
+}
+
+static void igt_stats_ensure_capacity(igt_stats_t *stats,
+ unsigned int n_additional_values)
+{
+ unsigned int new_n_values = stats->n_values + n_additional_values;
+ unsigned int new_capacity;
+
+ if (new_n_values <= stats->capacity)
+ return;
+
+ new_capacity = get_new_capacity(new_n_values);
+ stats->values = realloc(stats->values,
+ sizeof(*stats->values) * new_capacity);
+ igt_assert(stats->values);
+
+ stats->capacity = new_capacity;
+
+ free(stats->sorted);
+ stats->sorted = NULL;
+}
+
/**
* igt_stats_init:
* @stats: An #igt_stats_t instance
@@ -78,9 +109,7 @@ void igt_stats_init(igt_stats_t *stats, unsigned int capacity)
{
memset(stats, 0, sizeof(*stats));
- stats->values = calloc(capacity, sizeof(*stats->values));
- igt_assert(stats->values);
- stats->capacity = capacity;
+ igt_stats_ensure_capacity(stats, capacity);
stats->min = U64_MAX;
stats->max = 0;
@@ -156,7 +185,8 @@ void igt_stats_set_population(igt_stats_t *stats, bool full_population)
*/
void igt_stats_push(igt_stats_t *stats, uint64_t value)
{
- igt_assert(stats->n_values < stats->capacity);
+ igt_stats_ensure_capacity(stats, 1);
+
stats->values[stats->n_values++] = value;
stats->mean_variance_valid = false;
@@ -181,6 +211,8 @@ void igt_stats_push_array(igt_stats_t *stats,
{
unsigned int i;
+ igt_stats_ensure_capacity(stats, n_values);
+
for (i = 0; i < n_values; i++)
igt_stats_push(stats, values[i]);
}
@@ -240,6 +272,12 @@ static void igt_stats_ensure_sorted_values(igt_stats_t *stats)
return;
if (!stats->sorted) {
+ /*
+ * igt_stats_ensure_capacity() will free ->sorted when the
+ * capacity increases, which also correspond to an invalidation
+ * of the sorted array. We'll then reallocate it here on
+ * demand.
+ */
stats->sorted = calloc(stats->capacity, sizeof(*stats->values));
igt_assert(stats->sorted);
}