summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2020-01-28 12:13:50 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2020-01-28 12:13:50 +0000
commit7378f04882677d2e51ffc7f7ed96cc72c949717b (patch)
tree3dedae94af56922cf022c2d8a7bb3ada0a2ff912
parent087395e0a9f47829fe63de3c37810c3e49f38cf7 (diff)
Implement delete() and @map[key] access.
-rw-r--r--usr.sbin/btrace/TODO1
-rw-r--r--usr.sbin/btrace/bt_parse.y70
-rw-r--r--usr.sbin/btrace/bt_parser.h4
-rw-r--r--usr.sbin/btrace/btrace.c32
-rw-r--r--usr.sbin/btrace/btrace.h3
-rw-r--r--usr.sbin/btrace/map.c63
6 files changed, 116 insertions, 57 deletions
diff --git a/usr.sbin/btrace/TODO b/usr.sbin/btrace/TODO
index 4cd60171f47..f709815ddcc 100644
--- a/usr.sbin/btrace/TODO
+++ b/usr.sbin/btrace/TODO
@@ -10,7 +10,6 @@ Missing features:
- @ = lhist(x, min, max, step)
- @ = min(x)
- @ = max(x)
-- delete(@map[key])
Improvements:
diff --git a/usr.sbin/btrace/bt_parse.y b/usr.sbin/btrace/bt_parse.y
index 494b771403a..f69f256d6eb 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.4 2020/01/28 12:09:19 mpi Exp $ */
+/* $OpenBSD: bt_parse.y,v 1.5 2020/01/28 12:13:49 mpi Exp $ */
/*
* Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
@@ -62,9 +62,9 @@ struct bt_var *bv_find(const char *);
struct bt_arg *bv_get(const char *);
struct bt_stmt *bv_set(const char *, struct bt_arg *);
-struct bt_smt *bn_set(const char *, struct bt_arg *, struct bt_arg *);
-struct bt_stmt *bm_fn(enum bt_action, const char *, struct bt_arg *,
- struct bt_arg *);
+struct bt_arg *bm_get(const char *, struct bt_arg *);
+struct bt_stmt *bm_set(const char *, struct bt_arg *, struct bt_arg *);
+struct bt_stmt *bm_fn(enum bt_action, struct bt_arg *, struct bt_arg *);
/*
* Lexer
@@ -101,16 +101,16 @@ static int yylex(void);
%token COMM HZ KSTACK USTACK NSECS PID RETVAL TID
/* Functions */
%token F_CLEAR F_DELETE F_EXIT F_PRINT F_PRINTF F_TIME F_ZERO
-/* Map funcitons */
+/* Map functions */
%token M_COUNT
%token <v.string> STRING CSTRING
%token <v.number> NUMBER
%type <v.string> gvar
-%type <v.i> filterval oper builtin func0 func1 funcn mfunc1 mapfunc
+%type <v.i> filterval oper builtin fn0 fn1 fnN mfn0 mfn1
%type <v.probe> probe
%type <v.filter> predicate
%type <v.stmt> action stmt stmtlist
-%type <v.arg> arg arglist marg term
+%type <v.arg> arg arglist map marg term
%type <v.rtype> beginend
%%
@@ -166,19 +166,22 @@ builtin : PID { $$ = B_AT_BI_PID; }
| RETVAL { $$ = B_AT_BI_RETVAL; }
;
-func0 : F_EXIT { $$ = B_AC_EXIT; }
+fn0 : F_EXIT { $$ = B_AC_EXIT; }
;
-func1 : F_CLEAR { $$ = B_AC_CLEAR; }
+fn1 : F_CLEAR { $$ = B_AC_CLEAR; }
| F_TIME { $$ = B_AC_TIME; }
| F_ZERO { $$ = B_AC_ZERO; }
;
-funcn : F_PRINTF { $$ = B_AC_PRINTF; }
+fnN : F_PRINTF { $$ = B_AC_PRINTF; }
| F_PRINT { $$ = B_AC_PRINT; }
;
-mapfunc : M_COUNT '(' ')' { $$ = B_AT_MF_COUNT; }
+mfn0 : M_COUNT '(' ')' { $$ = B_AT_MF_COUNT; }
+ ;
+
+mfn1 : F_DELETE { $$ = B_AC_DELETE; }
;
term : '(' term ')' { $$ = $2; }
@@ -189,18 +192,22 @@ term : '(' term ')' { $$ = $2; }
| NUMBER { $$ = ba_new($1, B_AT_LONG); }
| builtin { $$ = ba_new(NULL, $1); }
| gvar { $$ = bv_get($1); }
+ | map { $$ = $1; }
+ ;
+
+gvar : '@' STRING { $$ = $2; }
+
+map : gvar '[' arg ']' { $$ = bm_get($1, $3); }
;
marg : arg { $$ = $1; }
- | mapfunc { $$ = ba_new(NULL, $1); };
+ | mfn0 { $$ = ba_new(NULL, $1); };
;
arg : CSTRING { $$ = ba_new($1, B_AT_STR); }
| term
;
-gvar : '@' STRING { $$ = $2; }
-
arglist : arg
| arglist ',' arg { $$ = ba_append($1, $3); }
;
@@ -208,9 +215,10 @@ arglist : arg
stmt : '\n' { $$ = NULL; }
| gvar '=' arg ';' { $$ = bv_set($1, $3); }
| gvar '[' arg ']' '=' marg ';' { $$ = bm_set($1, $3, $6); }
- | funcn '(' arglist ')' ';' { $$ = bs_new($1, $3, NULL); }
- | func1 '(' arg ')' ';' { $$ = bs_new($1, $3, NULL); }
- | func0 '(' ')' ';' { $$ = bs_new($1, NULL, NULL); }
+ | fnN '(' arglist ')' ';' { $$ = bs_new($1, $3, NULL); }
+ | fn1 '(' arg ')' ';' { $$ = bs_new($1, $3, NULL); }
+ | fn0 '(' ')' ';' { $$ = bs_new($1, NULL, NULL); }
+ | mfn1 '(' map ')' ';' { $$ = bm_fn($1, $3, NULL); }
;
stmtlist : stmt
@@ -441,22 +449,36 @@ bv_get(const char *vname)
}
struct bt_stmt *
-bm_fn(enum bt_action mact, const char *mname, struct bt_arg *mkey,
- struct bt_arg *mval)
+bm_fn(enum bt_action mact, struct bt_arg *ba, struct bt_arg *mval)
+{
+ return bs_new(mact, ba, (struct bt_var *)mval);
+}
+
+/* Create a 'map store' statement to assign a value to a map entry. */
+struct bt_stmt *
+bm_set(const char *mname, struct bt_arg *mkey, struct bt_arg *mval)
{
+ struct bt_arg *ba;
struct bt_var *bv;
bv = bv_find(mname);
if (bv == NULL)
bv = bv_new(mname);
- return bs_new(mact, ba_append(mval, mkey), bv);
+ ba = ba_new(bv, B_AT_MAP);
+ ba->ba_key = mkey;
+ return bs_new(B_AC_INSERT, ba, (struct bt_var *)mval);
}
-/* Create a 'map store' statement to assign a value to a map entry. */
-struct bt_stmt *
-bm_set(const char *mname, struct bt_arg *mkey, struct bt_arg *mval)
+/* Create an argument that points to a variable and attach a key to it. */
+struct bt_arg *
+bm_get(const char *mname, struct bt_arg *mkey)
{
- return bm_fn(B_AC_INSERT, mname, mkey, mval);
+ struct bt_arg *ba;
+
+ ba = bv_get(mname);
+ ba->ba_type = B_AT_MAP;
+ ba->ba_key = mkey;
+ return ba;
}
struct keyword {
diff --git a/usr.sbin/btrace/bt_parser.h b/usr.sbin/btrace/bt_parser.h
index 4083faddbc6..392331576ed 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.2 2020/01/27 14:15:25 mpi Exp $ */
+/* $OpenBSD: bt_parser.h,v 1.3 2020/01/28 12:13:49 mpi Exp $ */
/*
* Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
@@ -98,10 +98,12 @@ struct bt_var {
struct bt_arg {
SLIST_ENTRY(bt_arg) ba_next;
void *ba_value;
+ struct bt_arg *ba_key; /* key for maps */
enum bt_argtype {
B_AT_STR = 1, /* C-style string */
B_AT_LONG, /* Number (integer) */
B_AT_VAR, /* global variable (@var) */
+ B_AT_MAP, /* global map (@map[]) */
B_AT_BI_PID,
B_AT_BI_TID,
diff --git a/usr.sbin/btrace/btrace.c b/usr.sbin/btrace/btrace.c
index 13175d0dba3..c5048233cf5 100644
--- a/usr.sbin/btrace/btrace.c
+++ b/usr.sbin/btrace/btrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: btrace.c,v 1.2 2020/01/27 14:15:25 mpi Exp $ */
+/* $OpenBSD: btrace.c,v 1.3 2020/01/28 12:13:49 mpi Exp $ */
/*
* Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
@@ -675,14 +675,16 @@ stmt_clear(struct bt_stmt *bs)
void
stmt_delete(struct bt_stmt *bs, struct dt_evt *dtev)
{
- struct bt_arg *bkey = SLIST_FIRST(&bs->bs_args);
- struct bt_var *bv = bs->bs_var;
-
- assert(SLIST_NEXT(bkey, ba_next) == NULL);
+ struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args);
+ struct bt_var *bv = bmap->ba_value;
- map_delete(bv, ba2hash(bkey, dtev));
+ assert(bmap->ba_type == B_AT_MAP);
+ assert(bs->bs_var == NULL);
+ bkey = bmap->ba_key;
debug("map=%p '%s' delete key=%p\n", bv->bv_value, bv->bv_name, bkey);
+
+ map_delete(bv, ba2hash(bkey, dtev));
}
/*
@@ -694,16 +696,18 @@ stmt_delete(struct bt_stmt *bs, struct dt_evt *dtev)
void
stmt_insert(struct bt_stmt *bs, struct dt_evt *dtev)
{
- struct bt_arg *bkey, *bval = SLIST_FIRST(&bs->bs_args);
- struct bt_var *bv = bs->bs_var;
+ struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args);
+ struct bt_arg *bval = (struct bt_arg *)bs->bs_var;
+ struct bt_var *bv = bmap->ba_value;
- bkey = SLIST_NEXT(bval, ba_next);
- assert(SLIST_NEXT(bkey, ba_next) == NULL);
-
- map_insert(bv, ba2hash(bkey, dtev), bval);
+ assert(bmap->ba_type == B_AT_MAP);
+ assert(SLIST_NEXT(bval, ba_next) == NULL);
+ bkey = bmap->ba_key;
debug("map=%p '%s' insert key=%p bval=%p\n", bv->bv_value, bv->bv_name,
bkey, bval);
+
+ map_insert(bv, ba2hash(bkey, dtev), bval);
}
/*
@@ -802,6 +806,7 @@ stmt_zero(struct bt_stmt *bs)
debug("map=%p '%s' zero\n", bv->bv_value, bv->bv_name);
}
+
struct bt_arg *
ba_read(struct bt_arg *ba)
{
@@ -936,6 +941,9 @@ ba2str(struct bt_arg *ba, struct dt_evt *dtev)
snprintf(buf, sizeof(buf) - 1, "%ld", (long)dtev->dtev_sysretval);
str = buf;
break;
+ case B_AT_MAP:
+ str = ba2str(map_get(ba->ba_value, ba2str(ba->ba_key, dtev)), dtev);
+ break;
case B_AT_VAR:
str = ba2str(ba_read(ba), dtev);
break;
diff --git a/usr.sbin/btrace/btrace.h b/usr.sbin/btrace/btrace.h
index df99fb6fe06..dc87b49cb91 100644
--- a/usr.sbin/btrace/btrace.h
+++ b/usr.sbin/btrace/btrace.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: btrace.h,v 1.1 2020/01/21 16:24:55 mpi Exp $ */
+/* $OpenBSD: btrace.h,v 1.2 2020/01/28 12:13:49 mpi Exp $ */
/*
* Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
@@ -40,6 +40,7 @@ int kelf_snprintsym(char *, size_t, unsigned long);
/* map.c */
void map_clear(struct bt_var *);
void map_delete(struct bt_var *, const char *);
+struct bt_arg *map_get(struct bt_var *, const char *);
void map_insert(struct bt_var *, const char *,
struct bt_arg *);
void map_print(struct bt_var *, size_t);
diff --git a/usr.sbin/btrace/map.c b/usr.sbin/btrace/map.c
index eaf9559972d..97abb6efbf5 100644
--- a/usr.sbin/btrace/map.c
+++ b/usr.sbin/btrace/map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: map.c,v 1.1 2020/01/21 16:24:55 mpi Exp $ */
+/* $OpenBSD: map.c,v 1.2 2020/01/28 12:13:49 mpi Exp $ */
/*
* Copyright (c) 2020 Martin Pieuchot <mpi@openbsd.org>
@@ -43,7 +43,8 @@ struct mentry {
struct bt_arg *mval;
};
-int mcmp(struct mentry *, struct mentry *);
+int mcmp(struct mentry *, struct mentry *);
+struct mentry *mget(struct mtree *, const char *);
RB_GENERATE(mtree, mentry, mlink, mcmp);
@@ -53,6 +54,25 @@ mcmp(struct mentry *me0, struct mentry *me1)
return strncmp(me0->mkey, me1->mkey, KLEN - 1);
}
+struct mentry *
+mget(struct mtree *map, const char *key)
+{
+ struct mentry me, *mep;
+
+ strlcpy(me.mkey, key, KLEN);
+ mep = RB_FIND(mtree, map, &me);
+ if (mep == NULL) {
+ mep = calloc(1, sizeof(struct mentry));
+ if (mep == NULL)
+ err(1, "mentry: calloc");
+
+ strlcpy(mep->mkey, key, KLEN);
+ RB_INSERT(mtree, map, mep);
+ }
+
+ return mep;
+}
+
void
map_clear(struct bt_var *bv)
{
@@ -77,15 +97,30 @@ map_delete(struct bt_var *bv, const char *key)
struct mentry me, *mep;
strlcpy(me.mkey, key, KLEN);
- mep = RB_REMOVE(mtree, map, &me);
- free(mep);
+ mep = RB_FIND(mtree, map, &me);
+ if (mep != NULL) {
+ RB_REMOVE(mtree, map, mep);
+ free(mep);
+ }
}
+struct bt_arg *
+map_get(struct bt_var *bv, const char *key)
+{
+ struct mtree *map = (struct mtree *)bv->bv_value;
+ struct mentry *mep;
+
+ mep = mget(map, key);
+ if (mep->mval == NULL)
+ mep->mval = ba_new(0, B_AT_LONG);
+
+ return mep->mval;
+}
void
map_insert(struct bt_var *bv, const char *key, struct bt_arg *bval)
{
struct mtree *map = (struct mtree *)bv->bv_value;
- struct mentry me, *mep;
+ struct mentry *mep;
long val;
if (map == NULL) {
@@ -95,17 +130,7 @@ map_insert(struct bt_var *bv, const char *key, struct bt_arg *bval)
bv->bv_value = (struct bt_arg *)map;
}
- strlcpy(me.mkey, key, KLEN);
- mep = RB_FIND(mtree, map, &me);
- if (mep == NULL) {
- mep = calloc(1, sizeof(struct mentry));
- if (mep == NULL)
- err(1, "mentry: calloc");
-
- strlcpy(mep->mkey, key, KLEN);
- RB_INSERT(mtree, map, mep);
- }
-
+ mep = mget(map, key);
switch (bval->ba_type) {
case B_AT_MF_COUNT:
if (mep->mval == NULL)
@@ -116,6 +141,7 @@ map_insert(struct bt_var *bv, const char *key, struct bt_arg *bval)
break;
case B_AT_STR:
case B_AT_LONG:
+ free(mep->mval);
mep->mval = bval;
break;
default:
@@ -123,12 +149,13 @@ map_insert(struct bt_var *bv, const char *key, struct bt_arg *bval)
}
}
+static struct bt_arg nullba = { {NULL }, (void *)0, NULL, B_AT_LONG };
+static struct bt_arg maxba = { { NULL }, (void *)LONG_MAX, NULL, B_AT_LONG };
+
/* Print at most `top' entries of the map ordered by value. */
void
map_print(struct bt_var *bv, size_t top)
{
- static struct bt_arg nullba = { { NULL }, (void *)0, B_AT_LONG };
- static struct bt_arg maxba = { { NULL }, (void *)LONG_MAX, B_AT_LONG };
struct mtree *map = (void *)bv->bv_value;
struct mentry *mep, *mcur;
struct bt_arg *bhigh, *bprev;