From: Steven Rostedt <rostedt@goodmis.org>
To: linux-trace-devel@vger.kernel.org
Cc: Ross Zwisler <zwisler@google.com>,
Stevie Alvarez <stevie.6strings@gmail.com>
Subject: Re: [PATCH v3 00/18] libtraceeval histogram: Updates
Date: Wed, 16 Aug 2023 21:35:18 -0400 [thread overview]
Message-ID: <20230816213518.58eafe61@gandalf.local.home> (raw)
In-Reply-To: <20230817013310.88582-1-rostedt@goodmis.org>
On Wed, 16 Aug 2023 21:32:52 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> Changes since v2: https://lore.kernel.org/all/20230811053940.1408424-1-rostedt@goodmis.org/
The diff between this version and the last version:
diff --git a/include/traceeval-hist.h b/include/traceeval-hist.h
index 315b66adb7ee..8e5a6451f399 100644
--- a/include/traceeval-hist.h
+++ b/include/traceeval-hist.h
@@ -67,11 +67,11 @@ union traceeval_data {
struct traceeval_type;
struct traceeval;
-/* struct traceeval_dynamic release function signature */
+/* release function callback on traceeval_data */
typedef void (*traceeval_data_release_fn)(const struct traceeval_type *type,
union traceeval_data *data);
-/* struct traceeval_dynamic compare function signature */
+/* 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,
@@ -160,6 +160,9 @@ int traceeval_insert(struct traceeval *teval,
const union traceeval_data *keys,
const union traceeval_data *vals);
+int traceeval_remove(struct traceeval *teval,
+ const union traceeval_data *keys);
+
int traceeval_query(struct traceeval *teval, const union traceeval_data *keys,
const union traceeval_data **results);
diff --git a/samples/task-eval.c b/samples/task-eval.c
index e0ef2d0bcb30..66d0c40dc0c8 100644
--- a/samples/task-eval.c
+++ b/samples/task-eval.c
@@ -215,7 +215,9 @@ static void update_process(struct task_data *tdata, const char *comm,
return;
case STOP:
ret = traceeval_query(tdata->teval_processes.start, keys, &results);
- if (ret <= 0)
+ if (ret < 0)
+ pdie("Could not query start process");
+ if (ret == 0)
return;
if (!results[0].number_64)
break;
@@ -264,7 +266,9 @@ get_process_data(struct task_data *tdata, const char *comm)
int ret;
ret = traceeval_query(tdata->teval_processes_data, keys, &results);
- if (ret <= 0)
+ if (ret < 0)
+ pdie("Could not query process data");
+ if (ret == 0)
return NULL;
data = results[0].pointer;
@@ -289,6 +293,8 @@ void set_process_data(struct task_data *tdata, const char *comm, void *data)
ret = traceeval_query(tdata->teval_processes_data, keys, &results);
if (ret > 0)
goto out; /* It already exists ? */
+ if (ret < 0)
+ pdie("Could not query process data");
new_vals[0].pointer = data;
ret = traceeval_insert(tdata->teval_processes_data, keys, new_vals);
@@ -328,13 +334,17 @@ static void update_cpu(struct teval_pair *teval_pair, int cpu,
if (results[0].number_64)
break;
}
+ if (ret < 0)
+ pdie("Could not query cpu start data");
ret = traceeval_insert(teval_pair->start, keys, vals);
if (ret < 0)
pdie("Could not start CPU");
break;
case STOP:
ret = traceeval_query(teval_pair->start, keys, &results);
- if (ret <= 0)
+ if (ret < 0)
+ pdie("Could not query cpu stop data");
+ if (ret == 0)
return;
if (!results[0].number_64)
@@ -400,7 +410,9 @@ static void update_thread(struct process_data *pdata, int tid,
return;
case STOP:
ret = traceeval_query(pdata->teval_threads.start, keys, &results);
- if (ret <= 0)
+ if (ret < 0)
+ pdie("Could not query thread start");
+ if (ret == 0)
return;
new_vals[0].number_64 = ts - results[0].number_64;
@@ -825,6 +837,8 @@ static void display_processes(struct traceeval *teval,
const char *comm = keys[0].cstring;
ret = traceeval_query(teval_data, keys, &results);
+ if (ret < 0)
+ pdie("Could not query iterator");
if (ret < 1)
continue; /* ?? */
diff --git a/src/eval-local.h b/src/eval-local.h
index c3ea920ed2e8..5c3918f17cc1 100644
--- a/src/eval-local.h
+++ b/src/eval-local.h
@@ -6,7 +6,7 @@
#define __hidden __attribute__((visibility ("hidden")))
-#define offset_of(type, field) (&(((type *)(NULL))->field))
+#define offset_of(type, field) ((size_t)(&(((type *)(NULL))->field)))
#define container_of(ptr, type, field) \
(type *)((void *)(ptr) - (void *)offset_of(type, field))
diff --git a/src/hash.c b/src/hash.c
index 221145efcbb9..82962fbba8d8 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -78,7 +78,7 @@ __hidden struct hash_item *hash_iter_next(struct hash_iter *iter)
struct hash_table *hash = container_of(iter, struct hash_table, iter);
struct hash_item *item;
- if (iter->current_bucket > HASH_SIZE(hash->bits))
+ if (iter->current_bucket >= HASH_SIZE(hash->bits))
return NULL;
item = iter->next_item;
diff --git a/src/histograms.c b/src/histograms.c
index cd68d4c834af..f35d1b2e583d 100644
--- a/src/histograms.c
+++ b/src/histograms.c
@@ -12,7 +12,6 @@
#include <stdio.h>
#include <traceeval-hist.h>
-
#include "eval-local.h"
/*
@@ -37,9 +36,9 @@ static void print_err(const char *fmt, ...)
* -1 for the other way around, and -2 on error.
*/
static int compare_traceeval_data(struct traceeval *teval,
+ struct traceeval_type *type,
const union traceeval_data *orig,
- const union traceeval_data *copy,
- struct traceeval_type *type)
+ const union traceeval_data *copy)
{
int i;
@@ -92,16 +91,16 @@ static int compare_traceeval_data(struct traceeval *teval,
* 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,
- struct traceeval_type *defs, size_t size)
+ const union traceeval_data *copy, size_t size)
{
int check;
size_t i;
/* compare data arrays */
for (i = 0; i < size; i++) {
- if ((check = compare_traceeval_data(teval, orig + i, copy + i, defs + i)))
+ if ((check = compare_traceeval_data(teval, defs + i, orig + i, copy + i)))
return check == -2 ? -1 : 0;
}
@@ -294,12 +293,12 @@ struct traceeval *traceeval_init(struct traceeval_type *keys,
ret = check_keys(keys);
if (ret < 0)
- goto fail;
+ goto fail_release;
if (vals) {
ret = check_vals(vals);
if (ret < 0)
- goto fail;
+ goto fail_release;
}
/* alloc key types */
@@ -463,7 +462,7 @@ static unsigned make_hash(struct traceeval *teval, const union traceeval_data *k
key += hash_number(val);
}
- return key & HASH_MASK(bits);
+ return key;
}
/*
@@ -489,8 +488,8 @@ static int get_entry(struct traceeval *teval, const union traceeval_data *keys,
for (iter = hash_iter_bucket(hist, key); (item = hash_iter_bucket_next(iter)); ) {
entry = container_of(item, struct entry, hash);
- check = compare_traceeval_data_set(teval, entry->keys, keys,
- teval->key_types, teval->nr_key_types);
+ check = compare_traceeval_data_set(teval, teval->key_types,
+ entry->keys, keys, teval->nr_key_types);
if (check)
break;
}
@@ -596,7 +595,7 @@ static int copy_traceeval_data(struct traceeval_type *type,
/*
* Free @data with respect to @size and @type.
*
- * Does not call release() if a copy() exists.
+ * Does not call the release() callback if a copy() exists.
*/
static void data_release(size_t size, union traceeval_data *data,
struct traceeval_type *type)
@@ -776,7 +775,7 @@ fail_entry:
*
* Frees the old vals field of @entry, unless an error occurs.
*
- * Return 1 on success, -1 on error.
+ * Return 0 on success, -1 on error.
*/
static int update_entry(struct traceeval *teval, struct entry *entry,
const union traceeval_data *vals)
@@ -789,7 +788,7 @@ static int update_entry(struct traceeval *teval, struct entry *entry,
size_t i;
if (!size)
- return 1;
+ return 0;
for (i = 0; i < size; i++) {
old[i] = copy[i];
@@ -798,11 +797,16 @@ static int update_entry(struct traceeval *teval, struct entry *entry,
vals + i, copy + i))
goto fail;
}
-
+ data_release(size, old, types);
return 0;
-
-fail:
- data_release(i, old, types);
+ fail:
+ /* Free the new values that were added */
+ data_release(i, copy, types);
+ /* Put back the old values */
+ for (i--; i >= 0; i--) {
+ copy_traceeval_data(types + i, NULL,
+ copy + i, old + i);
+ }
return -1;
}
@@ -930,6 +934,35 @@ int traceeval_insert(struct traceeval *teval,
return update_entry(teval, entry, vals);
}
+/**
+ * traceeval_remove - remove an item from the traceeval descriptor
+ * @teval: The descriptor to insert into
+ * @keys: The list of keys that defines what is being removed
+ *
+ * This is the opposite of traceeval_insert(). Instead of inserting
+ * an item into the traceeval historgram, it removes it.
+ *
+ * Returns 1 if it found and removed an item,
+ * 0 if it did not find an time matching @keys
+ * -1 if there was an error.
+ */
+int traceeval_remove(struct traceeval *teval,
+ const union traceeval_data *keys)
+{
+ struct hash_table *hist = teval->hist;
+ struct entry *entry;
+ int check;
+
+ entry = NULL;
+ check = get_entry(teval, keys, &entry);
+
+ if (check < 1)
+ return check;
+
+ hash_remove(hist, &entry->hash);
+ return 1;
+}
+
/**
* traceeval_iterator_put - release a given iterator
* @iter: The iterartor to release
@@ -942,7 +975,9 @@ void traceeval_iterator_put(struct traceeval_iterator *iter)
if (!iter)
return;
+ free(iter->direction);
free(iter->entries);
+ free(iter->sort);
free(iter);
}
@@ -1058,6 +1093,7 @@ int traceeval_iterator_sort(struct traceeval_iterator *iter, const char *sort_fi
bool *direction = iter->direction;
struct traceeval_type **sort = iter->sort;
struct traceeval_type *type;
+ int num_levels = level + 1;
type = find_sort_type(iter->teval, sort_field);
if (!type)
@@ -1074,21 +1110,21 @@ int traceeval_iterator_sort(struct traceeval_iterator *iter, const char *sort_fi
break;
}
- if ((level + 1) > iter->nr_sort) {
- sort = realloc(sort, sizeof(*sort) * (level + 1));
+ if (num_levels > iter->nr_sort) {
+ sort = realloc(sort, sizeof(*sort) * num_levels);
if (!sort)
return -1;
iter->sort = sort;
- direction = realloc(direction, sizeof(*direction) * (level + 1));
+ direction = realloc(direction, sizeof(*direction) * num_levels);
if (!direction)
return -1;
iter->direction = direction;
/* Make sure the newly allocated contain NULL */
- for (int i = iter->nr_sort; i < (level + 1); i++)
+ for (int i = iter->nr_sort; i < num_levels; i++)
sort[i] = NULL;
iter->nr_sort = level + 1;
@@ -1123,7 +1159,7 @@ static int iter_cmp(const void *A, const void *B, void *data)
dataB = &b->vals[type->index];
}
- ret = compare_traceeval_data(teval, dataA, dataB, type);
+ ret = compare_traceeval_data(teval, type, dataA, dataB);
if (ret)
return iter->direction[i] ? ret : ret * -1;
@@ -1182,6 +1218,7 @@ int traceeval_iterator_sort_custom(struct traceeval_iterator *iter,
iter_custom_cmp, &cust_data);
iter->needs_sort = false;
+ iter->next = 0;
return 0;
}
-- Steve
next prev parent reply other threads:[~2023-08-17 1:35 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-17 1:32 [PATCH v3 00/18] libtraceeval histogram: Updates Steven Rostedt
2023-08-17 1:32 ` [PATCH v3 01/18] libtraceeval histograms: Fix traceeval_results_release() error message Steven Rostedt
2023-08-17 1:32 ` [PATCH v3 02/18] libtraceeval: Add sample task-eval program Steven Rostedt
2023-08-17 1:32 ` [PATCH v3 03/18] libtraceeval hist: Add pointer and const string types Steven Rostedt
2023-08-17 1:32 ` [PATCH v3 04/18] libtraceeval histogram: Have cmp and release functions be generic Steven Rostedt
2023-08-17 1:32 ` [PATCH v3 05/18] libtraceeval histograms: Add traceeval struct to compare function Steven Rostedt
2023-08-17 1:32 ` [PATCH v3 06/18] libtraceeval histogram: Remove comparing of traceeval and types Steven Rostedt
2023-08-17 1:32 ` [PATCH v3 07/18] libtraceeval: Convert hist array into a hash table Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 08/18] libtraceeval histograms: Move hash functions into their own file Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 09/18] libtraceeval histogram: Label and check keys and values Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 10/18] libtraceeval histogram: Add updating of stats Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 11/18] libtraceeval histogram: Add iterator APIs Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 12/18] libtraceeval histogram: Add data copy callback Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 13/18] libtraceeval histogram: Do the release on updates Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 14/18] libtraceeval histogram: Use stack for old copy in update Steven Rostedt
2023-08-17 19:29 ` Ross Zwisler
2023-08-17 19:42 ` Steven Rostedt
2023-08-17 19:44 ` Ross Zwisler
2023-08-17 20:25 ` Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 15/18] libtraceeval histogram: Add traceeval_iterator_sort_custom() Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 16/18] libtraceeval histogram: Have traceeval_query() just give the pointer to results Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 17/18] libtraceeval samples: Update task-eval to use the histogram logic Steven Rostedt
2023-08-17 1:33 ` [PATCH v3 18/18] libtraceeval: Add traceeval_remove() Steven Rostedt
2023-08-17 20:12 ` Ross Zwisler
2023-08-17 1:35 ` Steven Rostedt [this message]
2023-08-17 20:13 ` [PATCH v3 00/18] libtraceeval histogram: Updates Ross Zwisler
2023-08-17 20:31 ` Steven Rostedt
2023-08-17 20:37 ` Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230816213518.58eafe61@gandalf.local.home \
--to=rostedt@goodmis.org \
--cc=linux-trace-devel@vger.kernel.org \
--cc=stevie.6strings@gmail.com \
--cc=zwisler@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).