From patchwork Wed Aug 9 03:13:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Rostedt X-Patchwork-Id: 13347361 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8633BC001DE for ; Wed, 9 Aug 2023 03:13:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229587AbjHIDNZ (ORCPT ); Tue, 8 Aug 2023 23:13:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45128 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230449AbjHIDNU (ORCPT ); Tue, 8 Aug 2023 23:13:20 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 095A11FCA for ; Tue, 8 Aug 2023 20:13:18 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id C4C5D6232A for ; Wed, 9 Aug 2023 03:13:17 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3BFA2C433C9; Wed, 9 Aug 2023 03:13:17 +0000 (UTC) Received: from rostedt by gandalf with local (Exim 4.96) (envelope-from ) id 1qTZdL-005Rvm-2w; Tue, 08 Aug 2023 23:13:15 -0400 From: Steven Rostedt To: linux-trace-devel@vger.kernel.org Cc: Stevie Alvarez , Ross Zwisler , "Steven Rostedt (Google)" Subject: [PATCH 3/6] libtraceeval histogram: Have cmp and release functions be generic Date: Tue, 8 Aug 2023 23:13:10 -0400 Message-Id: <20230809031313.1298605-4-rostedt@goodmis.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230809031313.1298605-1-rostedt@goodmis.org> References: <20230809031313.1298605-1-rostedt@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org From: "Steven Rostedt (Google)" Having the ability to override the compare function for a given type can be very advantageous. There's also no reason that any type could ask for a release callback to be called when the type is being released. It could be used for information as well as for freeing. Rename traceeval_dyn_cmp_fn to traceeval_data_cmp_fn and traceeval_dyn_release_fn to traceeval_data_release_fn and have them take the union traceeval_type instead of struct traceeval_dynamic. In the structure, rename dyn_cmp to just cmp, and dyn_release to just release. Signed-off-by: Steven Rostedt (Google) --- include/traceeval-hist.h | 33 +++++++++++++++------------------ src/histograms.c | 26 ++++++++++++++------------ 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/include/traceeval-hist.h b/include/traceeval-hist.h index 03e050cdbed4..996fcab1b92b 100644 --- a/include/traceeval-hist.h +++ b/include/traceeval-hist.h @@ -65,13 +65,13 @@ struct traceeval_dynamic { struct traceeval_type; /* struct traceeval_dynamic release function signature */ -typedef void (*traceeval_dyn_release_fn)(struct traceeval_type *, - struct traceeval_dynamic *); +typedef void (*traceeval_data_release_fn)(struct traceeval_type *, + union traceeval_data *); /* struct traceeval_dynamic compare function signature */ -typedef int (*traceeval_dyn_cmp_fn)(struct traceeval_dynamic *, - struct traceeval_dynamic *, - struct traceeval_type *); +typedef int (*traceeval_data_cmp_fn)(const union traceeval_data *, + const union traceeval_data *, + struct traceeval_type *); /* * struct traceeval_type - Describes the type of a traceevent_data instance @@ -79,8 +79,8 @@ typedef int (*traceeval_dyn_cmp_fn)(struct traceeval_dynamic *, * @name: The string name of the traceeval_data * @flags: flags to describe the traceeval_data * @id: User specified identifier - * @dyn_release: For dynamic types called on release (ignored for other types) - * @dyn_cmp: A way to compare dynamic types (ignored for other types) + * @data_release: An optional callback for when the data is being released + * @data_cmp: An optional callback to specify a way to compare the type * * The traceeval_type structure defines expectations for a corresponding * traceeval_data instance for a traceeval histogram instance. Used to @@ -91,29 +91,26 @@ typedef int (*traceeval_dyn_cmp_fn)(struct traceeval_dynamic *, * which each relate to distinct user defined struct traceeval_dynamic * 'sub-types'. * - * For flexibility, @dyn_cmp() and @dyn_release() take a struct + * For flexibility, @data_cmp() and @data_release() take a struct * traceeval_type instance. This allows the user to distinguish between * different sub-types of struct traceeval_dynamic within a single * callback function by examining the @id field. This is not a required * approach, merely one that is accommodated. * - * @dyn_cmp() is used to compare two struct traceeval_dynamic instances when a - * corresponding struct traceeval_type is reached with its type field set to - * TRACEEVAL_TYPE_DYNAMIC. It should return 0 on equality, 1 if the first - * argument is greater than the second, -1 for the other way around, and -2 on - * error. + * @data_cmp() is used to override the default compare of a type. This is + * required to compare types of TRACEEVAL_TYPE_DYNAMIC. It should return 0 + * on equality, 1 if the first argument is greater than the second, + * -1 for the other way around, and -2 on error. * - * dyn_release() is used during traceeval_release() to release a union - * traceeval_data's struct traceeval_dynamic field when the corresponding - * traceeval_type type is set to TRACEEVAL_TYPE_DYNAMIC. + * data_release() is called when a data element is being released (or freed). */ struct traceeval_type { char *name; enum traceeval_data_type type; size_t flags; size_t id; - traceeval_dyn_release_fn dyn_release; - traceeval_dyn_cmp_fn dyn_cmp; + traceeval_data_release_fn release; + traceeval_data_cmp_fn cmp; }; /* Statistics about a given entry element */ diff --git a/src/histograms.c b/src/histograms.c index a59542afdea1..f35fccb1d4fe 100644 --- a/src/histograms.c +++ b/src/histograms.c @@ -89,9 +89,9 @@ static int compare_traceeval_type(struct traceeval_type *orig, return 1; if (orig[i].id != copy[i].id) return 1; - if (orig[i].dyn_release != copy[i].dyn_release) + if (orig[i].release != copy[i].release) return 1; - if (orig[i].dyn_cmp != copy[i].dyn_cmp) + if (orig[i].cmp != copy[i].cmp) return 1; // make sure both names are same type @@ -127,6 +127,9 @@ static int compare_traceeval_data(union traceeval_data *orig, if (!copy) return 1; + if (type->cmp) + return type->cmp(orig, copy, type); + switch (type->type) { case TRACEEVAL_TYPE_STRING: i = strcmp(orig->string, copy->string); @@ -148,8 +151,7 @@ static int compare_traceeval_data(union traceeval_data *orig, compare_numbers_return(orig->number_8, copy->number_8); case TRACEEVAL_TYPE_DYNAMIC: - if (type->dyn_cmp) - return type->dyn_cmp(orig->dyn_data, copy->dyn_data, type); + /* If it didn't specify a cmp function, then punt */ return 0; default: @@ -235,8 +237,8 @@ static int compare_hist(struct traceeval *orig, struct traceeval *copy) * * This compares the values of the key definitions, value definitions, and * inserted data between @orig and @copy in order. It does not compare - * by memory address, except for struct traceeval_type's dyn_release() and - * dyn_cmp() fields. + * by memory address, except for struct traceeval_type's release() and + * cmp() fields. * * Returns 0 if @orig and @copy are the same, 1 if not, and -1 on error. */ @@ -450,14 +452,14 @@ static void clean_data(union traceeval_data *data, struct traceeval_type *defs, } for (i = 0; i < size; i++) { + if (defs[i].release) { + defs[i].release(defs + i, data + i); + continue; + } switch (defs[i].type) { case TRACEEVAL_TYPE_STRING: free(data[i].string); break; - case TRACEEVAL_TYPE_DYNAMIC: - if (defs[i].dyn_release) - defs[i].dyn_release(defs + i, data[i].dyn_data); - break; default: break; } @@ -506,7 +508,7 @@ static void hist_table_release(struct traceeval *teval) * it must call traceeval_release(). * * This frees all internally allocated data of @teval and will call the - * corresponding dyn_release() functions registered for keys and values of + * corresponding release() functions registered for keys and values of * type TRACEEVAL_TYPE_DYNAMIC. */ void traceeval_release(struct traceeval *teval) @@ -588,7 +590,7 @@ static int copy_traceeval_data(struct traceeval_type *type, /* * Free @data with respect to @size and @type. * - * Does not call dyn_release on type TRACEEVAL_TYPE_DYNAMIC. + * Does not call release on type TRACEEVAL_TYPE_DYNAMIC. */ static void data_release(size_t size, union traceeval_data **data, struct traceeval_type *type)