From: "Steven Rostedt (Google)" <rostedt@xxxxxxxxxxx> In the update, instead of using the heap, use the stack to save the old values. This should save time where it does not need to allocate and then free the value list to do an update. Signed-off-by: Steven Rostedt (Google) <rostedt@xxxxxxxxxxx> --- src/histograms.c | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/histograms.c b/src/histograms.c index 8c73d8cd9f45..643a550422f6 100644 --- a/src/histograms.c +++ b/src/histograms.c @@ -598,17 +598,23 @@ static int copy_traceeval_data(struct traceeval_type *type, * * Does not call release() if a copy() exists. */ -static void data_release(size_t size, union traceeval_data **data, - struct traceeval_type *type) +static void data_release(size_t size, union traceeval_data *data, + struct traceeval_type *type) { for (size_t i = 0; i < size; i++) { /* A copy should handle releases */ if (type[i].release && !type[i].copy) - type[i].release(&type[i], &(*data)[i]); + type[i].release(&type[i], &data[i]); if (type[i].type == TRACEEVAL_TYPE_STRING) - free((*data)[i].string); + free(data[i].string); } +} + +static void data_release_and_free(size_t size, union traceeval_data **data, + struct traceeval_type *type) +{ + data_release(size, *data, type); free(*data); *data = NULL; } @@ -642,7 +648,7 @@ static int copy_traceeval_data_set(size_t size, struct traceeval_type *type, return 1; fail: - data_release(i, copy, type); + data_release_and_free(i, copy, type); return -1; } @@ -701,7 +707,7 @@ void traceeval_results_release(struct traceeval *teval, return; } - data_release(teval->nr_val_types, &results, teval->val_types); + data_release_and_free(teval->nr_val_types, &results, teval->val_types); } static struct entry *create_hist_entry(struct traceeval *teval, @@ -757,7 +763,7 @@ static int create_entry(struct traceeval *teval, return 0; fail: - data_release(teval->nr_key_types, &new_keys, teval->key_types); + data_release_and_free(teval->nr_key_types, &new_keys, teval->key_types); fail_stats: free(entry->val_stats); @@ -772,20 +778,34 @@ fail_entry: * * Frees the old vals field of @entry, unless an error occurs. * - * Return 0 on success, -1 on error. + * Return 1 on success, -1 on error. */ static int update_entry(struct traceeval *teval, struct entry *entry, const union traceeval_data *vals) { - union traceeval_data *new_vals; + struct traceeval_stat *stats = entry->val_stats; + struct traceeval_type *types = teval->val_types; + union traceeval_data *copy = entry->vals; + union traceeval_data old[teval->nr_val_types]; + size_t size = teval->nr_val_types; + size_t i; - if (copy_traceeval_data_set(teval->nr_val_types, teval->val_types, - vals, entry->val_stats, &new_vals) == -1) - return -1; + if (!size) + return 1; + + for (i = 0; i < size; i++) { + old[i] = copy[i]; + + if (copy_traceeval_data(types + i, stats + i, + vals + i, copy + i)) + goto fail; + } - clean_data_set(entry->vals, teval->val_types, teval->nr_val_types); - entry->vals = new_vals; return 0; + +fail: + data_release(i, old, types); + return -1; } struct traceeval_stat *traceeval_stat(struct traceeval *teval, -- 2.40.1
![]() |