Re: [PATCH 4/9] libtraceeval: Add traceeval_iterator_remove()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Aug 17, 2023 at 06:24:17PM -0400, Steven Rostedt wrote:
> From: "Steven Rostedt (Google)" <rostedt@xxxxxxxxxxx>
> 
> Add an API traceeval_iterator_remove() that is safe to call in the
> traceeval_iterator_next() loop. Currently, traceeval_remove() can also be
> called "safely", but that may change in the future.
> 
> The main difference between traceeval_remove() and traceeval_iterator_remove()
> is that that traceeval_iterator_remove() will NULL out the entry in the
> sort array, and use this in the other iterator functions. If the entry is
> NULL, it will not be returned.
> 
> Signed-off-by: Steven Rostedt (Google) <rostedt@xxxxxxxxxxx>
> ---
>  include/traceeval-hist.h |  1 +
>  src/histograms.c         | 48 ++++++++++++++++++++++++++++++++++++----
>  2 files changed, 45 insertions(+), 4 deletions(-)
> 
> diff --git a/include/traceeval-hist.h b/include/traceeval-hist.h
> index d511c9c5f14c..7d67673ce7e5 100644
> --- a/include/traceeval-hist.h
> +++ b/include/traceeval-hist.h
> @@ -190,5 +190,6 @@ int traceeval_iterator_query(struct traceeval_iterator *iter,
>  			     const union traceeval_data **results);
>  struct traceeval_stat *traceeval_iterator_stat(struct traceeval_iterator *iter,
>  					       struct traceeval_type *type);
> +int traceeval_iterator_remove(struct traceeval_iterator *iter);
>  
>  #endif /* __LIBTRACEEVAL_HIST_H__ */
> diff --git a/src/histograms.c b/src/histograms.c
> index fddd0f3587e2..0fbd9e0a353e 100644
> --- a/src/histograms.c
> +++ b/src/histograms.c
> @@ -1305,10 +1305,13 @@ int traceeval_iterator_next(struct traceeval_iterator *iter,
>  		iter->next = 0;
>  	}
>  
> -	if (iter->next >= iter->nr_entries)
> -		return 0;
> +	do {
> +		if (iter->next >= iter->nr_entries)
> +			return 0;
> +
> +		entry = iter->entries[iter->next++];
> +	} while (!entry);
>  
> -	entry = iter->entries[iter->next++];
>  	*keys = entry->keys;
>  	return 1;
>  }
> @@ -1338,6 +1341,9 @@ int traceeval_iterator_query(struct traceeval_iterator *iter,
>  		return 0;
>  
>  	entry = iter->entries[iter->next - 1];
> +	if (!entry)
> +		return 0;
> +
>  	*results = entry->vals;
>  
>  	return 1;
> @@ -1363,5 +1369,39 @@ struct traceeval_stat *traceeval_iterator_stat(struct traceeval_iterator *iter,
>  		return NULL;
>  
>  	entry = iter->entries[iter->next - 1];
> -	return &entry->val_stats[type->index];
> +	return entry ? &entry->val_stats[type->index] : NULL;
> +}
> +
> +/**
> + * traceeval_iterator_remove - remove the current iterator entry
> + * @iter: The iterator to remove the entry from
> + *
> + * This will remove the current entry from the histogram.
> + * This is useful if the current entry should be removed. It will not
> + * affect the traceeval_iterator_next().
> + *
> + * Returns 1 if it successfully removed the entry, 0 if for some reason
> + * there was no "current entry" (called before traceeval_iterator_next()).
> + * or -1 on error.
> + */
> +int traceeval_iterator_remove(struct traceeval_iterator *iter)
> +{
> +	struct traceeval *teval = iter->teval;
> +	struct hash_table *hist = teval->hist;
> +	struct entry *entry;
> +
> +	if (iter->next < 1 || iter->next > iter->nr_entries)
> +		return 0;
> +
> +	entry = iter->entries[iter->next - 1];
> +	if (!entry)
> +		return 0;
> +
> +	hash_remove(hist, &entry->hash);

Are we leaking 'entry' after we've removed it from the hash?

I think we need to call free_entry() in both traceeval_iterator_remove() as
well as traceeval_remove(), just like we do in the loop in
hist_table_release().

> +
> +	/* The entry no longer exists */
> +	iter->entries[iter->next - 1] = NULL;
> +	teval->update_counter++;
> +
> +	return 1;
>  }
> -- 
> 2.40.1
> 



[Index of Archives]     [Linux USB Development]     [Linux USB Development]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux