diff --git a/regress/usr.sbin/btrace/Makefile b/regress/usr.sbin/btrace/Makefile index 9deea955b9d..0144980b202 100644 --- a/regress/usr.sbin/btrace/Makefile +++ b/regress/usr.sbin/btrace/Makefile @@ -1,10 +1,10 @@ -# $OpenBSD: Makefile,v 1.2 2020/01/28 12:07:12 mpi Exp $ +# $OpenBSD: Makefile,v 1.3 2020/01/28 16:39:51 mpi Exp $ BTRACE?= /usr/sbin/btrace # scripts that don't need /dev/dt BT_LANG_SCRIPTS= arithm beginend comments delete exit map maxoperand \ - multismts nsecs+var + min+max+sum multismts nsecs+var BT_KERN_SCRIPTS= diff --git a/regress/usr.sbin/btrace/min+max+sum.bt b/regress/usr.sbin/btrace/min+max+sum.bt new file mode 100644 index 00000000000..c3c06455dbd --- /dev/null +++ b/regress/usr.sbin/btrace/min+max+sum.bt @@ -0,0 +1,18 @@ +BEGIN +{ + @map[7] = 3; + printf("=> Print with one element\n"); + print(@map); + + @map[7] = min(5); + printf("=> Print after min:\n"); + print(@map); + + @map[7] = max(5); + printf("=> Print after max:\n"); + print(@map); + + @map[7] = sum(7); + printf("=> Print after sum:\n"); + print(@map); +} diff --git a/regress/usr.sbin/btrace/min+max+sum.ok b/regress/usr.sbin/btrace/min+max+sum.ok new file mode 100644 index 00000000000..af9b14aed10 --- /dev/null +++ b/regress/usr.sbin/btrace/min+max+sum.ok @@ -0,0 +1,8 @@ +=> Print with one element +@map[7]: 3 +=> Print after min: +@map[7]: 3 +=> Print after max: +@map[7]: 5 +=> Print after sum: +@map[7]: 12 diff --git a/usr.sbin/btrace/TODO b/usr.sbin/btrace/TODO index f709815ddcc..7773fe30598 100644 --- a/usr.sbin/btrace/TODO +++ b/usr.sbin/btrace/TODO @@ -5,11 +5,8 @@ Missing features: - scratch variable ($name) - `args', tracepoint arguments support (requires kernel work) - str() -- @ = sum(x) - @ = hist(x) - @ = lhist(x, min, max, step) -- @ = min(x) -- @ = max(x) Improvements: diff --git a/usr.sbin/btrace/bt_parse.y b/usr.sbin/btrace/bt_parse.y index 3817e90d84d..ee85b1bb83d 100644 --- a/usr.sbin/btrace/bt_parse.y +++ b/usr.sbin/btrace/bt_parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: bt_parse.y,v 1.7 2020/01/28 16:02:28 mpi Exp $ */ +/* $OpenBSD: bt_parse.y,v 1.8 2020/01/28 16:39:51 mpi Exp $ */ /* * Copyright (c) 2019 - 2020 Martin Pieuchot @@ -102,11 +102,11 @@ static int yylex(void); /* Functions */ %token F_CLEAR F_DELETE F_EXIT F_PRINT F_PRINTF F_TIME F_ZERO /* Map functions */ -%token M_COUNT +%token M_COUNT M_MAX M_MIN M_SUM %token STRING CSTRING %token NUMBER %type gvar -%type filterval oper builtin fn0 fn1 fnN mfn0 mfn1 +%type filterval oper builtin fn0 fn1 fnN mfn0 mfn1 mfnN %type probe %type predicate %type action stmt stmtlist @@ -180,12 +180,17 @@ fnN : F_PRINTF { $$ = B_AC_PRINTF; } | F_PRINT { $$ = B_AC_PRINT; } ; -mfn0 : M_COUNT '(' ')' { $$ = B_AT_MF_COUNT; } +mfn0 : M_COUNT { $$ = B_AT_MF_COUNT; } ; mfn1 : F_DELETE { $$ = B_AC_DELETE; } ; +mfnN : M_MAX { $$ = B_AT_MF_MAX; } + | M_MIN { $$ = B_AT_MF_MIN; } + | M_SUM { $$ = B_AT_MF_SUM; } + ; + term : '(' term ')' { $$ = $2; } | term '+' term { $$ = ba_op('+', $1, $3); } | term '-' term { $$ = ba_op('-', $1, $3); } @@ -203,7 +208,8 @@ map : gvar '[' arg ']' { $$ = bm_get($1, $3); } ; marg : arg { $$ = $1; } - | mfn0 { $$ = ba_new(NULL, $1); }; + | mfn0 '(' ')' { $$ = ba_new(NULL, $1); } + | mfnN '(' arg ')' { $$ = ba_new($3, $1); } ; arg : CSTRING { $$ = ba_new($1, B_AT_STR); } @@ -523,11 +529,14 @@ lookup(char *s) { "exit", F_EXIT }, { "hz", HZ }, { "kstack", KSTACK }, + { "max", M_MAX }, + { "min", M_MIN }, { "nsecs", NSECS }, { "pid", PID }, { "print", F_PRINT }, { "printf", F_PRINTF }, { "retval", RETVAL }, + { "sum", M_SUM }, { "tid", TID }, { "time", F_TIME }, { "ustack", USTACK }, diff --git a/usr.sbin/btrace/bt_parser.h b/usr.sbin/btrace/bt_parser.h index 392331576ed..9c18fce9bb2 100644 --- a/usr.sbin/btrace/bt_parser.h +++ b/usr.sbin/btrace/bt_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bt_parser.h,v 1.3 2020/01/28 12:13:49 mpi Exp $ */ +/* $OpenBSD: bt_parser.h,v 1.4 2020/01/28 16:39:51 mpi Exp $ */ /* * Copyright (c) 2019 Martin Pieuchot @@ -124,7 +124,10 @@ struct bt_arg { B_AT_BI_ARGS, B_AT_BI_RETVAL, - B_AT_MF_COUNT, /* count() */ + B_AT_MF_COUNT, /* @map[key] = count() */ + B_AT_MF_MAX, /* @map[key] = max(nsecs) */ + B_AT_MF_MIN, /* @map[key] = min(pid) */ + B_AT_MF_SUM, /* @map[key] = sum(@elapsed) */ B_AT_OP_ADD, B_AT_OP_MINUS, diff --git a/usr.sbin/btrace/btrace.c b/usr.sbin/btrace/btrace.c index c5048233cf5..dccef997e14 100644 --- a/usr.sbin/btrace/btrace.c +++ b/usr.sbin/btrace/btrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: btrace.c,v 1.3 2020/01/28 12:13:49 mpi Exp $ */ +/* $OpenBSD: btrace.c,v 1.4 2020/01/28 16:39:51 mpi Exp $ */ /* * Copyright (c) 2019 - 2020 Martin Pieuchot @@ -84,7 +84,6 @@ void stmt_store(struct bt_stmt *, struct dt_evt *); void stmt_time(struct bt_stmt *, struct dt_evt *); void stmt_zero(struct bt_stmt *); struct bt_arg *ba_read(struct bt_arg *); -long ba2long(struct bt_arg *, struct dt_evt *); /* FIXME: use a real hash. */ #define ba2hash(_b, _e) ba2str((_b), (_e)) @@ -460,6 +459,9 @@ rules_setup(int fd) dtrq->dtrq_evtflags |= DTEVT_RETVAL; break; case B_AT_MF_COUNT: + case B_AT_MF_MAX: + case B_AT_MF_MIN: + case B_AT_MF_SUM: case B_AT_OP_ADD ... B_AT_OP_DIVIDE: break; default: @@ -952,6 +954,9 @@ ba2str(struct bt_arg *ba, struct dt_evt *dtev) str = buf; break; case B_AT_MF_COUNT: + case B_AT_MF_MAX: + case B_AT_MF_MIN: + case B_AT_MF_SUM: assert(0); break; default: diff --git a/usr.sbin/btrace/btrace.h b/usr.sbin/btrace/btrace.h index dc87b49cb91..8665ee870fc 100644 --- a/usr.sbin/btrace/btrace.h +++ b/usr.sbin/btrace/btrace.h @@ -1,4 +1,4 @@ -/* $OpenBSD: btrace.h,v 1.2 2020/01/28 12:13:49 mpi Exp $ */ +/* $OpenBSD: btrace.h,v 1.3 2020/01/28 16:39:51 mpi Exp $ */ /* * Copyright (c) 2019 - 2020 Martin Pieuchot @@ -29,6 +29,7 @@ struct bt_var; struct bt_stmt; /* btrace.c */ +long ba2long(struct bt_arg *, struct dt_evt *); const char *ba2str(struct bt_arg *, struct dt_evt *); long bacmp(struct bt_arg *, struct bt_arg *); diff --git a/usr.sbin/btrace/map.c b/usr.sbin/btrace/map.c index 97abb6efbf5..1c4581b9824 100644 --- a/usr.sbin/btrace/map.c +++ b/usr.sbin/btrace/map.c @@ -1,4 +1,4 @@ -/* $OpenBSD: map.c,v 1.2 2020/01/28 12:13:49 mpi Exp $ */ +/* $OpenBSD: map.c,v 1.3 2020/01/28 16:39:51 mpi Exp $ */ /* * Copyright (c) 2020 Martin Pieuchot @@ -33,6 +33,14 @@ #include "bt_parser.h" #include "btrace.h" +#ifndef MIN +#define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b)) +#endif + +#ifndef MAX +#define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b)) +#endif + RB_HEAD(mtree, mentry); #define KLEN 64 @@ -132,6 +140,11 @@ map_insert(struct bt_var *bv, const char *key, struct bt_arg *bval) mep = mget(map, key); switch (bval->ba_type) { + case B_AT_STR: + case B_AT_LONG: + free(mep->mval); + mep->mval = bval; + break; case B_AT_MF_COUNT: if (mep->mval == NULL) mep->mval = ba_new(0, B_AT_LONG); @@ -139,10 +152,26 @@ map_insert(struct bt_var *bv, const char *key, struct bt_arg *bval) val++; mep->mval->ba_value = (void *)val; break; - case B_AT_STR: - case B_AT_LONG: - free(mep->mval); - mep->mval = bval; + case B_AT_MF_MAX: + if (mep->mval == NULL) + mep->mval = ba_new(0, B_AT_LONG); + val = (long)mep->mval->ba_value; + val = MAX(val, ba2long(bval->ba_value, NULL)); + mep->mval->ba_value = (void *)val; + break; + case B_AT_MF_MIN: + if (mep->mval == NULL) + mep->mval = ba_new(0, B_AT_LONG); + val = (long)mep->mval->ba_value; + val = MIN(val, ba2long(bval->ba_value, NULL)); + mep->mval->ba_value = (void *)val; + break; + case B_AT_MF_SUM: + if (mep->mval == NULL) + mep->mval = ba_new(0, B_AT_LONG); + val = (long)mep->mval->ba_value; + val += ba2long(bval->ba_value, NULL); + mep->mval->ba_value = (void *)val; break; default: errx(1, "no insert support for type %d", bval->ba_type);