Messages in this thread Patch in this message | | | Date | Sun, 22 Sep 2019 12:47:30 -0400 | From | Alex <> | Subject | [PATCH] perf: save RAM when filtering events |
| |
The code mentioned wanting to use an implementation of log10() in the dvb drivers. I am not aware why that specific implementation is mentioned. I used the implementation found in `math.h`.
I tested this patch passing 200 syscalls to filter on a `perf trace -e ${syscalls} ls` call. You can see the commands used and a snipped of the valgrind results here: https://termbin.com/k4of
Before: 61,910,110 bytes allocated After: 61,907,045 bytes allocated
perf used to allocate space in excess to build the filtering expressions. now perf only allocates the space necessary and not more.
Signed-off-by: Alex Diaz <alex@akdev.xyz> --- tools/perf/util/string.c | 25 ++++++++++++++++++++----- tools/perf/util/string2.h | 2 ++ 2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 52603876c548..4c3913a9e7e7 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c @@ -3,6 +3,7 @@ #include <linux/kernel.h> #include <linux/string.h> #include <stdlib.h> +#include <math.h>
#include <linux/ctype.h>
@@ -209,15 +210,29 @@ int strtailcmp(const char *s1, const char *s2) return 0; }
-char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints) +size_t calc_expr_buffer_size(const char *var, size_t nints, int *ints) { /* - * FIXME: replace this with an expression using log10() when we - * find a suitable implementation, maybe the one in the dvb drivers... + * Calculate the buffer for the expression: * - * "%s == %d || " = log10(MAXINT) * 2 + 8 chars for the operators + * "%s == %d || " + * length: strlen(var) + strlen(" == ") + log10(n) + strlen(" || ") + 1 */ - size_t size = nints * 28 + 1; /* \0 */ + size_t size = 0; + size_t num_len = 0; + const size_t var_len = strlen(var); + + for (size_t i = 0; i < nints; ++i) { + num_len = (ints[i] == 0) ? 1 : log10(ints[i]); + size += var_len + num_len + 9; + } + + return size; +} + +char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints) +{ + size_t size = calc_expr_buffer_size(var, nints, ints); size_t i, printed = 0; char *expr = malloc(size);
diff --git a/tools/perf/util/string2.h b/tools/perf/util/string2.h index 708805f5573e..28fbc782ad54 100644 --- a/tools/perf/util/string2.h +++ b/tools/perf/util/string2.h @@ -20,6 +20,8 @@ static inline bool strisglob(const char *str) } int strtailcmp(const char *s1, const char *s2);
+size_t calc_expr_buffer_size(const char *var, size_t nints, int *ints); + char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints);
static inline char *asprintf_expr_in_ints(const char *var, size_t nints, int *ints) -- 2.21.0
| |