From mboxrd@z Thu Jan 1 00:00:00 1970 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 189FBC41513 for ; Wed, 16 Aug 2023 15:42:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238375AbjHPPmM (ORCPT ); Wed, 16 Aug 2023 11:42:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44338 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344280AbjHPPl4 (ORCPT ); Wed, 16 Aug 2023 11:41:56 -0400 Received: from mail-oa1-x35.google.com (mail-oa1-x35.google.com [IPv6:2001:4860:4864:20::35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D959F26A8 for ; Wed, 16 Aug 2023 08:41:51 -0700 (PDT) Received: by mail-oa1-x35.google.com with SMTP id 586e51a60fabf-1c4de3b9072so2540017fac.3 for ; Wed, 16 Aug 2023 08:41:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692200511; x=1692805311; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=H5LfyDDwJeK47bOtyH8V99a4qo0dz0SuxNk8+vON57w=; b=o4GyAuEkTl7nNeJ6XGY1+foz0W6c0vbLU/dog9hmIbCOO2x+7cpF0cIFRxtLDElgrr EgD5PkER0yqqCgQUxy3VTUXYTVO/OcR+2NucWm9StpnWG+J0+x4SsPY/WgeWgQ2rYag+ vZTv9XIpEnn/PwvBoWvN/FNvwsLZPE6+j3uWnkHrKDkILx4yjEJ5JSzvmLkeJADd0Jg0 +ESG+dIXhY8OiKBK0WdMYHzZ+1GZU1lRavPFEOspAcYmIkQDMlg8w+e5c+yrlTZ7wbxp WWY1IYj6ax9Gvsiy11M2UwClAMawNsgH1aUpW010UoPjsZ5l6Nb/UqNRXkYJt6axplDw nS+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692200511; x=1692805311; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=H5LfyDDwJeK47bOtyH8V99a4qo0dz0SuxNk8+vON57w=; b=Qd6KR+8kR6NPD6BIqZL6yMYRxseeXTOS/ML9UbsT3au7kLl+ItNtQTeLQIrEnW1GOW tX1hCH60MGtU8Xr8Jn0HuFOZ0qSjJtbxAerjtoyjgr59Z7Hm7ozFvwWsG0vaitYsjUyk V3cFWN6fW6fUhZjYrNsG/9kyVzer8znfzfERzEkymbmJSSFhfVLq2KrhdamAdw7QJbaW Vm25P5ipfoROVkMdJS2rgDkcI44KhST0rzLFXPaXnTfIOuHf+pWywfBST+EQnRy277aX 4/xJw34o7lMZExVpJ1OqrMLmlrduBOmsA77llZklJFOk9QNHMkp/etRix7Tm6a4FJkgu TfTA== X-Gm-Message-State: AOJu0YwqaAeB+ikizPkLkHXr0wfUm9QF/TUwWcoDk6NuuTepitiKeyul s+CvaFAzkfgAVt4qlc537O8= X-Google-Smtp-Source: AGHT+IEQG72N4Xu/GFVROlFTXDtLplfzE8aEgo6syZhaZibyBVhQD/dfC43vLIdIKxFZXKalqTRMpQ== X-Received: by 2002:a05:6870:a10d:b0:1bf:8a8:dfa with SMTP id m13-20020a056870a10d00b001bf08a80dfamr2656838oae.11.1692200510603; Wed, 16 Aug 2023 08:41:50 -0700 (PDT) Received: from 3xKetch ([2601:180:8300:500::3c27]) by smtp.gmail.com with ESMTPSA id c12-20020a0cf2cc000000b0064711ec77b9sm3243201qvm.81.2023.08.16.08.41.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Aug 2023 08:41:49 -0700 (PDT) Date: Wed, 16 Aug 2023 11:41:45 -0400 From: Stevie Alvarez To: Steven Rostedt Cc: Linux Trace Devel , Ross Zwisler Subject: Re: [PATCH] libtraceeval histogram: Add type to traceeval_data and make it a structure Message-ID: <20230816154145.GA1462@3xKetch> References: <20230815193852.3e0a7328@gandalf.local.home> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20230815193852.3e0a7328@gandalf.local.home> Precedence: bulk List-ID: X-Mailing-List: linux-trace-devel@vger.kernel.org On Tue, Aug 15, 2023 at 07:38:52PM -0400, Steven Rostedt wrote: > From: "Steven Rostedt (Google)" > > Having a straight union for passing in the data that must match the types > is dangerous and prone for buggy code. If some data doesn't match its > type, there's nothing to catch it. > > Instead of having a union traceeval_data of each type, have it be a > structure with a "type" field follow by a union, where the type defines > what kind of data it is. > > Add helper macros to make it easy to define the data when using it. > > Note, most of this patch was just a find and replace of "union" to > "struct", and then the added helper macros, and the updates to the sample > code. Nothing else was modified to get it to work. > > Note, there isn't a "dynamic" helper code, as I still do not know of a use > case for it. > > Signed-off-by: Steven Rostedt (Google) > --- > > Ross, as we discussed on our 1:1, I think this is the better way to go. It > labels the data with their types, and I even think the helper macros look > better (just by looking at the sample code). > > include/traceeval-hist.h | 71 +++++++++++++++++++++--------------- > samples/task-eval.c | 78 ++++++++++++++++++---------------------- > src/eval-local.h | 4 +-- > src/histograms.c | 66 +++++++++++++++++----------------- > 4 files changed, 112 insertions(+), 107 deletions(-) > > diff --git a/include/traceeval-hist.h b/include/traceeval-hist.h > index 8e5a6451f399..d0bee7c02aa0 100644 > --- a/include/traceeval-hist.h > +++ b/include/traceeval-hist.h > @@ -52,45 +52,60 @@ struct traceeval_dynamic { > * Trace data entry for a traceeval histogram > * Constitutes keys and values. > */ > -union traceeval_data { > - struct traceeval_dynamic dyn_data; > - char *string; > - const char *cstring; > - void *pointer; > - unsigned long number; > - unsigned long long number_64; > - unsigned int number_32; > - unsigned short number_16; > - unsigned char number_8; > +struct traceeval_data { > + enum traceeval_data_type type; > + union { > + struct traceeval_dynamic dyn_data; > + char *string; > + const char *cstring; > + void *pointer; > + unsigned long number; > + unsigned long long number_64; > + unsigned int number_32; > + unsigned short number_16; > + unsigned char number_8; > + }; > }; > > +#define __TRACEEVAL_DATA(data_type, member, data) \ > + { .type = TRACEEVAL_TYPE_##data_type, .member = (data) } > + > +#define DEFINE_TRACEEVAL_NUMBER(data) __TRACEEVAL_DATA(NUMBER, number, data) > +#define DEFINE_TRACEEVAL_NUMBER_8(data) __TRACEEVAL_DATA(NUMBER_8, number_8, data) > +#define DEFINE_TRACEEVAL_NUMBER_16(data) __TRACEEVAL_DATA(NUMBER_16, number_16, data) > +#define DEFINE_TRACEEVAL_NUMBER_32(data) __TRACEEVAL_DATA(NUMBER_32, number_32, data) > +#define DEFINE_TRACEEVAL_NUMBER_64(data) __TRACEEVAL_DATA(NUMBER_64, number_64, data) > +#define DEFINE_TRACEEVAL_STRING(data) __TRACEEVAL_DATA(STRING, string, data) > +#define DEFINE_TRACEEVAL_CSTRING(data) __TRACEEVAL_DATA(STRING, cstring, data) > +#define DEFINE_TRACEEVAL_POINTER(data) __TRACEEVAL_DATA(POINTER, pointer, data) > + > struct traceeval_type; > struct traceeval; > > /* release function callback on traceeval_data */ > typedef void (*traceeval_data_release_fn)(const struct traceeval_type *type, > - union traceeval_data *data); > + struct traceeval_data *data); > > /* compare function callback to compare traceeval_data */ > typedef int (*traceeval_data_cmp_fn)(struct traceeval *teval, > const struct traceeval_type *type, > - const union traceeval_data *A, > - const union traceeval_data *B); > + const struct traceeval_data *A, > + const struct traceeval_data *B); > > /* make a unique value */ > typedef int (*traceeval_data_hash_fn)(struct traceeval *teval, > const struct traceeval_type *type, > - const union traceeval_data *data); > + const struct traceeval_data *data); > > typedef int (*traceeval_data_copy_fn)(const struct traceeval_type *type, > - union traceeval_data *copy, > - const union traceeval_data *origin); > + struct traceeval_data *copy, > + const struct traceeval_data *origin); > > typedef int (*traceeval_cmp_fn)(struct traceeval *teval, > - const union traceeval_data *Akeys, > - const union traceeval_data *Avals, > - const union traceeval_data *Bkeys, > - const union traceeval_data *Bvals, > + const struct traceeval_data *Akeys, > + const struct traceeval_data *Avals, > + const struct traceeval_data *Bkeys, > + const struct traceeval_data *Bvals, > void *data); > > /* > @@ -157,20 +172,20 @@ struct traceeval *traceeval_init(struct traceeval_type *keys, > void traceeval_release(struct traceeval *teval); > > int traceeval_insert(struct traceeval *teval, > - const union traceeval_data *keys, > - const union traceeval_data *vals); > + const struct traceeval_data *keys, > + const struct traceeval_data *vals); > > int traceeval_remove(struct traceeval *teval, > - const union traceeval_data *keys); > + const struct traceeval_data *keys); > > -int traceeval_query(struct traceeval *teval, const union traceeval_data *keys, > - const union traceeval_data **results); > +int traceeval_query(struct traceeval *teval, const struct traceeval_data *keys, > + const struct traceeval_data **results); > > void traceeval_results_release(struct traceeval *teval, > - const union traceeval_data *results); > + const struct traceeval_data *results); > > struct traceeval_stat *traceeval_stat(struct traceeval *teval, > - const union traceeval_data *keys, > + const struct traceeval_data *keys, > struct traceeval_type *type); > > unsigned long long traceeval_stat_max(struct traceeval_stat *stat); > @@ -185,6 +200,6 @@ int traceeval_iterator_sort(struct traceeval_iterator *iter, const char *sort_fi > int traceeval_iterator_sort_custom(struct traceeval_iterator *iter, > traceeval_cmp_fn sort_fn, void *data); > int traceeval_iterator_next(struct traceeval_iterator *iter, > - const union traceeval_data **keys); > + const struct traceeval_data **keys); > > #endif /* __LIBTRACEEVAL_HIST_H__ */ > diff --git a/samples/task-eval.c b/samples/task-eval.c > index e0ef2d0bcb30..c2950b2d64b0 100644 > --- a/samples/task-eval.c > +++ b/samples/task-eval.c > @@ -190,21 +190,15 @@ static void update_process(struct task_data *tdata, const char *comm, > enum sched_state state, enum command cmd, > unsigned long long ts) > { > - union traceeval_data keys[] = { > - { > - .cstring = comm, > - }, > - { > - .number = state, > - }, > + struct traceeval_data keys[] = { > + DEFINE_TRACEEVAL_CSTRING( comm ), > + DEFINE_TRACEEVAL_NUMBER( state ), > }; > - union traceeval_data vals[] = { > - { > - .number_64 = ts, > - }, > + struct traceeval_data vals[] = { > + DEFINE_TRACEEVAL_NUMBER_64( ts ), > }; > - union traceeval_data new_vals[1] = { }; > - const union traceeval_data *results; > + struct traceeval_data new_vals[1] = { }; > + const struct traceeval_data *results; > int ret; > > switch (cmd) { > @@ -251,15 +245,11 @@ static void stop_process(struct task_data *tdata, const char *comm, > static struct process_data * > get_process_data(struct task_data *tdata, const char *comm) > { > - union traceeval_data keys[] = { > - { > - .cstring = comm, > - }, > - { > - .number = RUNNING, > - } > + struct traceeval_data keys[] = { > + DEFINE_TRACEEVAL_CSTRING( comm ), > + DEFINE_TRACEEVAL_NUMBER( RUNNING ), > }; > - const union traceeval_data *results; > + const struct traceeval_data *results; > void *data; > int ret; > > @@ -274,7 +264,7 @@ get_process_data(struct task_data *tdata, const char *comm) > > void set_process_data(struct task_data *tdata, const char *comm, void *data) > { > - union traceeval_data keys[] = { > + struct traceeval_data keys[] = { > { > .cstring = comm, > }, Is there a reason you stop using the macros to define your traceeval_data array elements? Or a better question: Are these struct traceeval_data instances exempt to needing a type field? And if so, why? -- Stevie > @@ -282,8 +272,8 @@ void set_process_data(struct task_data *tdata, const char *comm, void *data) > .number = RUNNING, > } > }; > - union traceeval_data new_vals[1] = { }; > - const union traceeval_data *results; > + struct traceeval_data new_vals[1] = { }; > + const struct traceeval_data *results; > int ret; > > ret = traceeval_query(tdata->teval_processes_data, keys, &results); > @@ -303,8 +293,8 @@ static void update_cpu(struct teval_pair *teval_pair, int cpu, > enum sched_state state, enum command cmd, > unsigned long long ts) > { > - const union traceeval_data *results; > - union traceeval_data keys[] = { > + const struct traceeval_data *results; > + struct traceeval_data keys[] = { > { > .number = cpu, > }, > @@ -312,12 +302,12 @@ static void update_cpu(struct teval_pair *teval_pair, int cpu, > .number = state, > } > }; > - union traceeval_data vals[] = { > + struct traceeval_data vals[] = { > { > .number_64 = ts, > }, > }; > - union traceeval_data new_vals[1] = { }; > + struct traceeval_data new_vals[1] = { }; > int ret; > > switch (cmd) { > @@ -375,8 +365,8 @@ static void update_thread(struct process_data *pdata, int tid, > enum sched_state state, enum command cmd, > unsigned long long ts) > { > - const union traceeval_data *results; > - union traceeval_data keys[] = { > + const struct traceeval_data *results; > + struct traceeval_data keys[] = { > { > .number = tid, > }, > @@ -384,12 +374,12 @@ static void update_thread(struct process_data *pdata, int tid, > .number = state, > } > }; > - union traceeval_data vals[] = { > + struct traceeval_data vals[] = { > { > .number_64 = ts, > }, > }; > - union traceeval_data new_vals[1] = { }; > + struct traceeval_data new_vals[1] = { }; > int ret; > > switch (cmd) { > @@ -634,16 +624,16 @@ static void print_microseconds(int idx, unsigned long long nsecs) > * If RUNNING is equal, then sort by COMM. > */ > static int compare_pdata(struct traceeval *teval_data, > - const union traceeval_data *Akeys, > - const union traceeval_data *Avals, > - const union traceeval_data *Bkeys, > - const union traceeval_data *Bvals, > + const struct traceeval_data *Akeys, > + const struct traceeval_data *Avals, > + const struct traceeval_data *Bkeys, > + const struct traceeval_data *Bvals, > void *data) > { > struct traceeval *teval = data; /* The deltas are here */ > - union traceeval_data keysA[] = { > + struct traceeval_data keysA[] = { > { .cstring = Akeys[0].cstring }, { .number = RUNNING } }; > - union traceeval_data keysB[] = { > + struct traceeval_data keysB[] = { > { .cstring = Bkeys[0].cstring }, { .number = RUNNING } }; > struct traceeval_stat *statA; > struct traceeval_stat *statB; > @@ -678,7 +668,7 @@ static int compare_pdata(struct traceeval *teval_data, > static void display_cpus(struct traceeval *teval) > { > struct traceeval_iterator *iter = traceeval_iterator_get(teval); > - const union traceeval_data *keys; > + const struct traceeval_data *keys; > struct traceeval_stat *stat; > int last_cpu = -1; > > @@ -750,7 +740,7 @@ static void display_state_times(int state, unsigned long long total) > static void display_threads(struct traceeval *teval) > { > struct traceeval_iterator *iter = traceeval_iterator_get(teval); > - const union traceeval_data *keys; > + const struct traceeval_data *keys; > struct traceeval_stat *stat; > int last_tid = -1; > > @@ -790,7 +780,7 @@ static void display_process_stats(struct traceeval *teval, > { > struct traceeval_stat *stat; > unsigned long long delta; > - union traceeval_data keys[] = { > + struct traceeval_data keys[] = { > { > .cstring = comm, > }, > @@ -814,13 +804,13 @@ static void display_processes(struct traceeval *teval, > struct traceeval *teval_data) > { > struct traceeval_iterator *iter = traceeval_iterator_get(teval_data); > - const union traceeval_data *keys; > + const struct traceeval_data *keys; > int ret; > > traceeval_iterator_sort_custom(iter, compare_pdata, teval); > > while (traceeval_iterator_next(iter, &keys) > 0) { > - const union traceeval_data *results; > + const struct traceeval_data *results; > struct process_data *pdata = NULL; > const char *comm = keys[0].cstring; > > @@ -843,7 +833,7 @@ static void display(struct task_data *tdata) > { > struct traceeval *teval = tdata->teval_cpus.stop; > struct traceeval_iterator *iter = traceeval_iterator_get(teval); > - const union traceeval_data *keys; > + const struct traceeval_data *keys; > struct traceeval_stat *stat; > unsigned long long total_time = 0; > unsigned long long idle_time = 0; > diff --git a/src/eval-local.h b/src/eval-local.h > index 5c3918f17cc1..848851f7ffc4 100644 > --- a/src/eval-local.h > +++ b/src/eval-local.h > @@ -56,8 +56,8 @@ struct traceeval_stat { > /* A key-value pair */ > struct entry { > struct hash_item hash; > - union traceeval_data *keys; > - union traceeval_data *vals; > + struct traceeval_data *keys; > + struct traceeval_data *vals; > struct traceeval_stat *val_stats; > }; > > diff --git a/src/histograms.c b/src/histograms.c > index 3f43f7201b65..a7d0643cfbbd 100644 > --- a/src/histograms.c > +++ b/src/histograms.c > @@ -37,8 +37,8 @@ static void print_err(const char *fmt, ...) > */ > static int compare_traceeval_data(struct traceeval *teval, > struct traceeval_type *type, > - const union traceeval_data *orig, > - const union traceeval_data *copy) > + const struct traceeval_data *orig, > + const struct traceeval_data *copy) > { > int i; > > @@ -86,14 +86,14 @@ static int compare_traceeval_data(struct traceeval *teval, > } > > /* > - * Compare arrays of union traceeval_data's with respect to @def. > + * Compare arrays of struct traceeval_data's with respect to @def. > * > * Return 1 if @orig and @copy are the same, 0 if not, and -1 on error. > */ > static int compare_traceeval_data_set(struct traceeval *teval, > struct traceeval_type *defs, > - union traceeval_data *orig, > - const union traceeval_data *copy, size_t size) > + struct traceeval_data *orig, > + const struct traceeval_data *copy, size_t size) > { > int check; > size_t i; > @@ -335,7 +335,7 @@ fail: > /* > * Frees dynamic data in @data if @type specifies a dynamic data type. > */ > -static void clean_data(union traceeval_data *data, struct traceeval_type *type) > +static void clean_data(struct traceeval_data *data, struct traceeval_type *type) > { > if (type->release) > type->release(type, data); > @@ -352,7 +352,7 @@ static void clean_data(union traceeval_data *data, struct traceeval_type *type) > /* > * Free any specified dynamic data in @data. > */ > -static void clean_data_set(union traceeval_data *data, struct traceeval_type *defs, > +static void clean_data_set(struct traceeval_data *data, struct traceeval_type *defs, > size_t size) > { > size_t i; > @@ -431,7 +431,7 @@ void traceeval_release(struct traceeval *teval) > free(teval); > } > > -static unsigned make_hash(struct traceeval *teval, const union traceeval_data *keys, > +static unsigned make_hash(struct traceeval *teval, const struct traceeval_data *keys, > int bits) > { > const struct traceeval_type *types = teval->key_types; > @@ -470,7 +470,7 @@ static unsigned make_hash(struct traceeval *teval, const union traceeval_data *k > * > * Returns 1 on success, 0 if no match found, -1 on error. > */ > -static int get_entry(struct traceeval *teval, const union traceeval_data *keys, > +static int get_entry(struct traceeval *teval, const struct traceeval_data *keys, > struct entry **result) > { > struct hash_table *hist = teval->hist; > @@ -506,8 +506,8 @@ static int get_entry(struct traceeval *teval, const union traceeval_data *keys, > */ > static int copy_traceeval_data(struct traceeval_type *type, > struct traceeval_stat *stat, > - const union traceeval_data *orig, > - union traceeval_data *copy) > + const struct traceeval_data *orig, > + struct traceeval_data *copy) > { > unsigned long long val; > > @@ -597,7 +597,7 @@ static int copy_traceeval_data(struct traceeval_type *type, > * > * Does not call the release() callback if a copy() exists. > */ > -static void data_release(size_t size, union traceeval_data *data, > +static void data_release(size_t size, struct traceeval_data *data, > struct traceeval_type *type) > { > for (size_t i = 0; i < size; i++) { > @@ -610,7 +610,7 @@ static void data_release(size_t size, union traceeval_data *data, > } > } > > -static void data_release_and_free(size_t size, union traceeval_data **data, > +static void data_release_and_free(size_t size, struct traceeval_data **data, > struct traceeval_type *type) > { > data_release(size, *data, type); > @@ -624,9 +624,9 @@ static void data_release_and_free(size_t size, union traceeval_data **data, > * Returns 1 on success, -1 on error. > */ > static int copy_traceeval_data_set(size_t size, struct traceeval_type *type, > - const union traceeval_data *orig, > + const struct traceeval_data *orig, > struct traceeval_stat *stats, > - union traceeval_data **copy) > + struct traceeval_data **copy) > { > size_t i; > > @@ -669,8 +669,8 @@ fail: > * > * Returns 1 if found, 0 if not found, and -1 on error. > */ > -int traceeval_query(struct traceeval *teval, const union traceeval_data *keys, > - const union traceeval_data **results) > +int traceeval_query(struct traceeval *teval, const struct traceeval_data *keys, > + const struct traceeval_data **results) > { > struct entry *entry; > int check; > @@ -698,7 +698,7 @@ int traceeval_query(struct traceeval *teval, const union traceeval_data *keys, > * allow traceeval to clean up its references. > */ > void traceeval_results_release(struct traceeval *teval, > - const union traceeval_data *results) > + const struct traceeval_data *results) > { > if (!teval || !results) { > if (!teval) > @@ -708,7 +708,7 @@ void traceeval_results_release(struct traceeval *teval, > } > > static struct entry *create_hist_entry(struct traceeval *teval, > - const union traceeval_data *keys) > + const struct traceeval_data *keys) > { > struct hash_table *hist = teval->hist; > unsigned key = make_hash(teval, keys, hist->bits); > @@ -729,11 +729,11 @@ static struct entry *create_hist_entry(struct traceeval *teval, > * Returns 0 on success, -1 on error. > */ > static int create_entry(struct traceeval *teval, > - const union traceeval_data *keys, > - const union traceeval_data *vals) > + const struct traceeval_data *keys, > + const struct traceeval_data *vals) > { > - union traceeval_data *new_keys; > - union traceeval_data *new_vals; > + struct traceeval_data *new_keys; > + struct traceeval_data *new_vals; > struct entry *entry; > > entry = create_hist_entry(teval, keys); > @@ -778,12 +778,12 @@ fail_entry: > * Return 1 on success, -1 on error. > */ > static int update_entry(struct traceeval *teval, struct entry *entry, > - const union traceeval_data *vals) > + const struct traceeval_data *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]; > + struct traceeval_data *copy = entry->vals; > + struct traceeval_data old[teval->nr_val_types]; > size_t size = teval->nr_val_types; > size_t i; > > @@ -806,7 +806,7 @@ fail: > } > > struct traceeval_stat *traceeval_stat(struct traceeval *teval, > - const union traceeval_data *keys, > + const struct traceeval_data *keys, > struct traceeval_type *type) > { > struct entry *entry; > @@ -910,8 +910,8 @@ unsigned long long traceeval_stat_count(struct traceeval_stat *stat) > * Returns 0 on success, and -1 on error. > */ > int traceeval_insert(struct traceeval *teval, > - const union traceeval_data *keys, > - const union traceeval_data *vals) > + const struct traceeval_data *keys, > + const struct traceeval_data *vals) > { > struct entry *entry; > int check; > @@ -942,7 +942,7 @@ int traceeval_insert(struct traceeval *teval, > * -1 if there was an error. > */ > int traceeval_remove(struct traceeval *teval, > - const union traceeval_data *keys) > + const struct traceeval_data *keys) > { > struct hash_table *hist = teval->hist; > struct entry *entry; > @@ -1138,8 +1138,8 @@ static int iter_cmp(const void *A, const void *B, void *data) > > for (int i = 0; i < iter->nr_sort; i++) { > struct traceeval_type *type; > - union traceeval_data *dataA; > - union traceeval_data *dataB; > + struct traceeval_data *dataA; > + struct traceeval_data *dataB; > > type = iter->sort[i]; > > @@ -1225,7 +1225,7 @@ int traceeval_iterator_sort_custom(struct traceeval_iterator *iter, > * Returns 1 if another entry is returned, or 0 if not (or negative on error) > */ > int traceeval_iterator_next(struct traceeval_iterator *iter, > - const union traceeval_data **keys) > + const struct traceeval_data **keys) > { > struct entry *entry; > int ret; > -- > 2.40.1 >