summaryrefslogtreecommitdiff
path: root/sys/src/cmd/dtracy/act.c
diff options
context:
space:
mode:
authoraiju <devnull@localhost>2018-12-08 15:07:53 +0000
committeraiju <devnull@localhost>2018-12-08 15:07:53 +0000
commit58fa29447b845f91dfc2a6734f525ed47375393b (patch)
treee2ee80e7728e26bc74e1f667ea48968b11a24fc6 /sys/src/cmd/dtracy/act.c
parent03e60450c2acc20866867cc5d3649aaed07d0326 (diff)
dtracy: add support for aggregations
Diffstat (limited to 'sys/src/cmd/dtracy/act.c')
-rw-r--r--sys/src/cmd/dtracy/act.c79
1 files changed, 78 insertions, 1 deletions
diff --git a/sys/src/cmd/dtracy/act.c b/sys/src/cmd/dtracy/act.c
index 335d1bd23..063be6cb9 100644
--- a/sys/src/cmd/dtracy/act.c
+++ b/sys/src/cmd/dtracy/act.c
@@ -55,6 +55,27 @@ addprobe(char *s)
clause->probs[clause->nprob++] = strdup(s);
}
+static char *aggtypes[] = {
+ [AGGCNT] "count",
+ [AGGMIN] "min",
+ [AGGMAX] "max",
+ [AGGSUM] "sum",
+ [AGGAVG] "avg",
+ [AGGSTD] "std",
+};
+
+int
+aggtype(Symbol *s)
+{
+ int i;
+
+ for(i = 0; i < nelem(aggtypes); i++)
+ if(strcmp(s->name, aggtypes[i]) == 0)
+ return i;
+ error("%s unknown aggregation type", s->name);
+ return 0;
+}
+
void
addstat(int type, ...)
{
@@ -73,6 +94,19 @@ addstat(int type, ...)
case STATPRINT:
case STATPRINTF:
break;
+ case STATAGG:
+ s->agg.name = va_arg(va, Symbol *);
+ s->agg.key = va_arg(va, Node *);
+ s->agg.type = aggtype(va_arg(va, Symbol *));
+ s->agg.value = va_arg(va, Node *);
+ if(s->agg.type == AGGCNT){
+ if(s->agg.value != nil)
+ error("too many arguments for count()");
+ }else{
+ if(s->agg.value == nil)
+ error("need argument for %s()", aggtypes[s->agg.type]);
+ }
+ break;
default:
sysfatal("addstat: unknown type %d", type);
}
@@ -158,12 +192,26 @@ prepprintf(Node **arg, int narg, DTActGr *g, int *recoff)
(*arg)->str = fmtstrflush(&f);
}
+int aggid;
+
+int
+allagg(Clause *c)
+{
+ Stat *s;
+
+ for(s = c->stats; s < c->stats + c->nstats; s++)
+ if(s->type != STATAGG)
+ return 0;
+ return 1;
+}
+
DTClause *
mkdtclause(Clause *c)
{
DTClause *d;
Stat *s;
int recoff, i;
+ Node *n;
d = emalloc(sizeof(DTClause));
d->nprob = c->nprob;
@@ -175,7 +223,7 @@ mkdtclause(Clause *c)
for(s = c->stats; s < c->stats + c->nstats; s++)
switch(s->type){
case STATEXPR:
- actgradd(d->gr, (DTAct){ACTTRACE, codegen(s->n), 0});
+ actgradd(d->gr, (DTAct){ACTTRACE, codegen(s->n), 0, noagg});
break;
case STATPRINT:
for(i = 0; i < s->narg; i++)
@@ -184,7 +232,22 @@ mkdtclause(Clause *c)
case STATPRINTF:
prepprintf(s->arg, s->narg, d->gr, &recoff);
break;
+ case STATAGG: {
+ DTAgg agg = {.id = s->agg.type << 28 | 1 << 16 | aggid++};
+ assert(dtaunpackid(&agg) >= 0);
+ aggs = realloc(aggs, sizeof(Agg) * aggid);
+ memset(&aggs[aggid-1], 0, sizeof(Agg));
+ aggs[aggid-1].DTAgg = agg;
+ aggs[aggid-1].name = strdup(s->agg.name == nil ? "" : s->agg.name->name);
+ actgradd(d->gr, (DTAct){ACTAGGKEY, codegen(s->agg.key), 8, agg});
+ n = s->agg.value;
+ if(n == nil) n = node(ONUM, 0ULL);
+ actgradd(d->gr, (DTAct){ACTAGGVAL, codegen(n), 8, agg});
+ break;
}
+ }
+ if(allagg(c))
+ actgradd(d->gr, (DTAct){ACTCANCEL, codegen(node(ONUM, 0)), 0, noagg});
return d;
}
@@ -392,6 +455,7 @@ parseclause(Clause *cl, uchar *p, uchar *e, Enab *en, Biobuf *bp)
case STATPRINTF:
execprintf(s->arg, s->narg, p, e, en);
break;
+ case STATAGG: break;
default:
sysfatal("parseclause: unknown type %d", s->type);
}
@@ -546,6 +610,17 @@ dump(void)
print("\t\ttrace string (%d bytes)\n", a->size);
dumpexpr(a->p, "\t\t\t");
break;
+ case ACTAGGKEY:
+ print("\t\taggregation key (%s,%d,%d)\n", a->agg.type >= nelem(aggtypes) ? "???" : aggtypes[a->agg.type], a->agg.keysize, (u16int)a->agg.id);
+ dumpexpr(a->p, "\t\t\t");
+ break;
+ case ACTAGGVAL:
+ print("\t\taggregation value (%s,%d,%d)\n", a->agg.type >= nelem(aggtypes) ? "???" : aggtypes[a->agg.type], a->agg.keysize, (u16int)a->agg.id);
+ dumpexpr(a->p, "\t\t\t");
+ break;
+ case ACTCANCEL:
+ print("\t\tcancel record\n");
+ break;
default:
print("\t\t??? %d\n", a->type);
}
@@ -564,6 +639,8 @@ dump(void)
for(j = 0; j < s->narg; j++)
print("\t\t\targ %ε\n", s->arg[j]);
break;
+ case STATAGG:
+ break;
default:
print("\t\t??? %d\n", s->type);
}