diff options
-rw-r--r-- | elaborate.cxx | 30 | ||||
-rw-r--r-- | parse.cxx | 16 | ||||
-rw-r--r-- | runtime/stat-common.c | 109 | ||||
-rw-r--r-- | staptree.cxx | 66 | ||||
-rw-r--r-- | staptree.h | 14 | ||||
-rw-r--r-- | tapset-mark.cxx | 8 | ||||
-rw-r--r-- | tapset-utrace.cxx | 8 | ||||
-rw-r--r-- | tapset/syscalls2.stp | 8 | ||||
-rw-r--r-- | tapsets.cxx | 17 | ||||
-rwxr-xr-x | testsuite/buildok/print_histograms.stp | 4 | ||||
-rw-r--r-- | translate.cxx | 22 |
11 files changed, 138 insertions, 164 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index 1d7f1e0b..2446e4f8 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1283,19 +1283,16 @@ void add_global_var_display (systemtap_session& s) if (tapset_global) continue; - print_format* pf = new print_format; - probe* p = new probe; - probe_point* pl = new probe_point; probe_point::component* c = new probe_point::component("end"); - token* print_tok = new token; + probe_point* pl = new probe_point; + pl->components.push_back (c); + vector<derived_probe*> dps; block *b = new block; - pl->components.push_back (c); + probe* p = new probe; p->tok = l->tok; p->locations.push_back (pl); - print_tok->type = tok_identifier; - print_tok->content = "printf"; // Create a symbol symbol* g_sym = new symbol; @@ -1304,13 +1301,12 @@ void add_global_var_display (systemtap_session& s) g_sym->type = l->type; g_sym->referent = l; - pf->print_to_stream = true; - pf->print_with_format = true; - pf->print_with_delim = false; - pf->print_with_newline = false; - pf->print_char = false; + token* print_tok = new token; + print_tok->type = tok_identifier; + print_tok->content = "printf"; + + print_format* pf = print_format::create(print_tok); pf->raw_components += l->name; - pf->tok = print_tok; if (l->index_types.size() == 0) // Scalar { @@ -1358,15 +1354,9 @@ void add_global_var_display (systemtap_session& s) be->right = new literal_number(0); /* Create printf @count=0x0 in else block */ - print_format* pf_0 = new print_format; - pf_0->print_to_stream = true; - pf_0->print_with_format = true; - pf_0->print_with_delim = false; - pf_0->print_with_newline = false; - pf_0->print_char = false; + print_format* pf_0 = print_format::create(print_tok); pf_0->raw_components += l->name; pf_0->raw_components += " @count=0x0\\n"; - pf_0->tok = print_tok; pf_0->components = print_format::string_to_components(pf_0->raw_components); expr_statement* feb_else = new expr_statement; feb_else->value = pf_0; @@ -2352,8 +2352,6 @@ parser::parse_symbol () // now scrutinize this identifier for the various magic forms of identifier // (printf, @stat_op, and $var...) - bool pf_stream, pf_format, pf_delim, pf_newline, pf_char; - if (name == "@cast") { // type-punning time @@ -2410,19 +2408,11 @@ parser::parse_symbol () return sop; } - else if (print_format::parse_print(name, - pf_stream, pf_format, pf_delim, pf_newline, pf_char)) + else if (print_format *fmt = print_format::create(t)) { - print_format *fmt = new print_format; - fmt->tok = t; - fmt->print_to_stream = pf_stream; - fmt->print_with_format = pf_format; - fmt->print_with_delim = pf_delim; - fmt->print_with_newline = pf_newline; - fmt->print_char = pf_char; - expect_op("("); - if ((name == "print" || name == "println") && + if ((name == "print" || name == "println" || + name == "sprint" || name == "sprintln") && (peek_kw("@hist_linear") || peek_kw("@hist_log"))) { // We have a special case where we recognize diff --git a/runtime/stat-common.c b/runtime/stat-common.c index 7dabe708..e6fd3a11 100644 --- a/runtime/stat-common.c +++ b/runtime/stat-common.c @@ -53,14 +53,6 @@ static int needed_space(int64_t v) return space; } -static void reprint (int num, char *s) -{ - while (num > 0) { - _stp_print(s); - num--; - } -} - /* Given a bucket number for a log histogram, return the value. */ static int64_t _stp_bucket_to_val(int num) { @@ -138,12 +130,17 @@ static int _stp_val_to_bucket(int64_t val) #endif -static void _stp_stat_print_histogram (Hist st, stat *sd) +static void _stp_stat_print_histogram_buf(char *buf, size_t size, Hist st, stat *sd) { int scale, i, j, val_space, cnt_space; int low_bucket = -1, high_bucket = 0, over = 0, under = 0; - int64_t val, v, max = 0; - int eliding = 0; + int64_t val, v, valmax = 0; + int eliding = 0; + char *cur_buf = buf, *fake = buf; + char **bufptr = (buf == NULL ? &fake : &cur_buf); + +#define HIST_PRINTF(fmt, args...) \ + (*bufptr += _stp_snprintf(cur_buf, buf + size - cur_buf, fmt, ## args)) if (st->type != HIST_LOG && st->type != HIST_LINEAR) return; @@ -155,8 +152,8 @@ static void _stp_stat_print_histogram (Hist st, stat *sd) low_bucket = i; if (sd->histogram[i] > 0) high_bucket = i; - if (sd->histogram[i] > max) - max = sd->histogram[i]; + if (sd->histogram[i] > valmax) + valmax = sd->histogram[i]; } /* Touch up the bucket margin to show up to two zero-slots on @@ -185,53 +182,45 @@ static void _stp_stat_print_histogram (Hist st, stat *sd) if (high_bucket == st->buckets-1) over = 1; } - - if (max <= HIST_WIDTH) + + if (valmax <= HIST_WIDTH) scale = 1; else { - int64_t tmp = max; - int rem = do_div (tmp, HIST_WIDTH); + int64_t tmp = valmax; + int rem = do_div(tmp, HIST_WIDTH); scale = tmp; if (rem) scale++; } /* count space */ - cnt_space = needed_space (max); + cnt_space = needed_space(valmax); /* Compute value space */ if (st->type == HIST_LINEAR) { - i = needed_space (st->start) + under; - val_space = needed_space (st->start + st->interval * high_bucket) + over; + val_space = max(needed_space(st->start) + under, + needed_space(st->start + st->interval * high_bucket) + over); } else { - i = needed_space(_stp_bucket_to_val(high_bucket)); - val_space = needed_space(_stp_bucket_to_val(low_bucket)); + val_space = max(needed_space(_stp_bucket_to_val(high_bucket)), + needed_space(_stp_bucket_to_val(low_bucket))); } - if (i > val_space) - val_space = i; - + val_space = max(val_space, 5 /* = sizeof("value") */); /* print header */ - j = 0; - if (val_space > 5) /* 5 = sizeof("value") */ - j = val_space - 5; - else - val_space = 5; - for ( i = 0; i < j; i++) - _stp_print(" "); - _stp_print("value |"); - reprint (HIST_WIDTH, "-"); - _stp_print(" count\n"); - - eliding=0; - for (i = low_bucket; i <= high_bucket; i++) { - int over_under = 0; + HIST_PRINTF("%*s |", val_space, "value"); + for (j = 0; j < HIST_WIDTH; ++j) + HIST_PRINTF("-"); + HIST_PRINTF(" count\n"); + + eliding = 0; + for (i = low_bucket; i <= high_bucket; i++) { + const char *val_prefix = ""; /* Elide consecutive zero buckets. Specifically, skip this row if it is zero and some of its nearest neighbours are also zero. Don't elide zero buckets if HIST_ELISION is negative */ if ((long)HIST_ELISION >= 0) { - int k, elide=1; + int k, elide = 1; /* Can't elide more than the total # of buckets */ int max_elide = min_t(long, HIST_ELISION, st->buckets); int min_bucket = low_bucket; @@ -254,8 +243,7 @@ static void _stp_stat_print_histogram (Hist st, stat *sd) about to print a new one. So let's print a mark on the vertical axis to represent the missing rows. */ if (eliding) { - reprint (val_space, " "); - _stp_print(" ~\n"); + HIST_PRINTF("%*s ~\n", val_space, ""); eliding = 0; } } @@ -264,38 +252,33 @@ static void _stp_stat_print_histogram (Hist st, stat *sd) if (i == 0) { /* underflow */ val = st->start; - over_under = 1; + val_prefix = "<"; } else if (i == st->buckets-1) { /* overflow */ val = st->start + (i - 2) * st->interval; - over_under = 1; - } else + val_prefix = ">"; + } else val = st->start + (i - 1) * st->interval; } else val = _stp_bucket_to_val(i); - reprint (val_space - needed_space(val) - over_under, " "); + HIST_PRINTF("%*s%lld |", val_space - needed_space(val), val_prefix, val); - if (over_under) { - if (i == 0) - _stp_printf("<%lld", val); - else if (i == st->buckets-1) - _stp_printf(">%lld", val); - else - _stp_printf("%lld", val); - } else - _stp_printf("%lld", val); - _stp_print(" |"); - /* v = s->histogram[i] / scale; */ v = sd->histogram[i]; - do_div (v, scale); - - reprint (v, "@"); - reprint (HIST_WIDTH - v + 1 + cnt_space - needed_space(sd->histogram[i]), " "); - _stp_printf ("%lld\n", sd->histogram[i]); + do_div(v, scale); + + for (j = 0; j < v; ++j) + HIST_PRINTF("@"); + HIST_PRINTF("%*lld\n", HIST_WIDTH - v + 1 + cnt_space, sd->histogram[i]); } - _stp_print_char('\n'); + HIST_PRINTF("\n"); +#undef HIST_PRINTF +} + +static void _stp_stat_print_histogram(Hist st, stat *sd) +{ + _stp_stat_print_histogram_buf(NULL, 0, st, sd); _stp_print_flush(); } diff --git a/staptree.cxx b/staptree.cxx index 090f0bd3..bc552454 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -405,52 +405,56 @@ void functioncall::print (ostream& o) const } -bool -print_format::parse_print(const std::string &name, - bool &stream, bool &format, bool &delim, bool &newline, bool &_char) +print_format* +print_format::create(const token *t) { - const char *n = name.c_str(); + bool stream, format, delim, newline, _char; + const char *n = t->content.c_str(); stream = true; format = delim = newline = _char = false; if (strcmp(n, "print_char") == 0) + _char = true; + else { - _char = true; - return true; - } - - if (*n == 's') - { - stream = false; - ++n; - } + if (*n == 's') + { + stream = false; + ++n; + } - if (0 != strncmp(n, "print", 5)) - return false; - n += 5; + if (0 != strncmp(n, "print", 5)) + return NULL; + n += 5; - if (*n == 'f') - { - format = true; - ++n; - } - else - { - if (*n == 'd') - { - delim = true; + if (*n == 'f') + { + format = true; ++n; } + else + { + if (*n == 'd') + { + delim = true; + ++n; + } - if (*n == 'l' && *(n+1) == 'n') - { - newline = true; - n += 2; + if (*n == 'l' && *(n+1) == 'n') + { + newline = true; + n += 2; + } } + + if (*n != '\0') + return NULL; } - return (*n == '\0'); + print_format *pf = new print_format(stream, format, delim, newline, _char); + pf->tok = t; + return pf; } @@ -373,10 +373,6 @@ struct print_format: public expression } }; - print_format() - : hist(NULL) - {} - std::string raw_components; std::vector<format_component> components; format_component delimiter; @@ -385,11 +381,17 @@ struct print_format: public expression static std::string components_to_string(std::vector<format_component> const & components); static std::vector<format_component> string_to_components(std::string const & str); - static bool parse_print(const std::string &name, bool &stream, - bool &format, bool &delim, bool &newline, bool &_char); + static print_format* create(const token *t); void print (std::ostream& o) const; void visit (visitor* u); + +private: + print_format(bool stream, bool format, bool delim, bool newline, bool _char): + print_to_stream(stream), print_with_format(format), + print_with_delim(delim), print_with_newline(newline), + print_char(_char), hist(NULL) + {} }; diff --git a/tapset-mark.cxx b/tapset-mark.cxx index b70098e3..fc9cb274 100644 --- a/tapset-mark.cxx +++ b/tapset-mark.cxx @@ -142,15 +142,9 @@ mark_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) else if (e->base_name == "$$vars" || e->base_name == "$$parms") { //copy from tracepoint - print_format* pf = new print_format; token* pf_tok = new token(*e->tok); pf_tok->content = "sprintf"; - pf->tok = pf_tok; - pf->print_to_stream = false; - pf->print_with_format = true; - pf->print_with_delim = false; - pf->print_with_newline = false; - pf->print_char = false; + print_format* pf = print_format::create(pf_tok); for (unsigned i = 0; i < mark_args.size(); ++i) { diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx index b731293c..abc9759f 100644 --- a/tapset-utrace.cxx +++ b/tapset-utrace.cxx @@ -448,15 +448,9 @@ utrace_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) if (e->base_name == "$$parms") { // copy from tracepoint - print_format* pf = new print_format; token* pf_tok = new token(*e->tok); pf_tok->content = "sprintf"; - pf->tok = pf_tok; - pf->print_to_stream = false; - pf->print_with_format = true; - pf->print_with_delim = false; - pf->print_with_newline = false; - pf->print_char = false; + print_format* pf = print_format::create(pf_tok); target_symbol_seen = true; diff --git a/tapset/syscalls2.stp b/tapset/syscalls2.stp index 5e97aef5..47aba9b4 100644 --- a/tapset/syscalls2.stp +++ b/tapset/syscalls2.stp @@ -61,14 +61,21 @@ probe syscall.compat_nanosleep.return = kernel.function("compat_sys_nanosleep"). # long compat_sys_nfsservctl(int cmd, struct compat_nfsctl_arg __user *arg, # union compat_nfsctl_res __user *res) # +%( CONFIG_NFSD == "[ym]" || CONFIG_COMPAT == "y" %? probe syscall.nfsservctl = kernel.function("sys_nfsservctl").call ?, kernel.function("compat_sys_nfsservctl").call ? { name = "nfsservctl" cmd = $cmd +%( CONFIG_NFSD == "[ym]" %? argp_uaddr = $arg resp_uaddr = $res argstr = sprintf("%s, %p, %p", _nfsctl_cmd_str($cmd), $arg, $res) +%: + argp_uaddr = $notused + resp_uaddr = $notused2 + argstr = sprintf("/* NI_SYSCALL */ %s, %p, %p", _nfsctl_cmd_str($cmd), $notused, $notused2) +%) } probe syscall.nfsservctl.return = kernel.function("sys_nfsservctl").return ?, kernel.function("compat_sys_nfsservctl").return ? @@ -76,6 +83,7 @@ probe syscall.nfsservctl.return = kernel.function("sys_nfsservctl").return ?, name = "nfsservctl" retstr = returnstr(1) } +%) # nice _______________________________________________________ # long sys_nice(int increment) diff --git a/tapsets.cxx b/tapsets.cxx index 5182bdd4..ba6f4ee4 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -2135,7 +2135,6 @@ dwarf_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) return; target_symbol *tsym = new target_symbol; - print_format* pf = new print_format; // Convert $$parms to sprintf of a list of parms and active local vars // which we recursively evaluate @@ -2148,12 +2147,7 @@ dwarf_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) pf_tok->type = tok_identifier; pf_tok->content = "sprint"; - pf->tok = pf_tok; - pf->print_to_stream = false; - pf->print_with_format = true; - pf->print_with_delim = false; - pf->print_with_newline = false; - pf->print_char = false; + print_format* pf = print_format::create(pf_tok); if (q.has_return && (e->base_name == "$$return")) { @@ -5618,8 +5612,6 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) } else if (e->base_name == "$$vars" || e->base_name == "$$parms") { - print_format* pf = new print_format; - // Convert $$vars to sprintf of a list of vars which we recursively evaluate // NB: we synthesize a new token here rather than reusing // e->tok, because print_format::print likes to use @@ -5627,12 +5619,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) token* pf_tok = new token(*e->tok); pf_tok->content = "sprintf"; - pf->tok = pf_tok; - pf->print_to_stream = false; - pf->print_with_format = true; - pf->print_with_delim = false; - pf->print_with_newline = false; - pf->print_char = false; + print_format* pf = print_format::create(pf_tok); for (unsigned i = 0; i < args.size(); ++i) { diff --git a/testsuite/buildok/print_histograms.stp b/testsuite/buildok/print_histograms.stp index 945606a0..3e5dc88f 100755 --- a/testsuite/buildok/print_histograms.stp +++ b/testsuite/buildok/print_histograms.stp @@ -26,5 +26,9 @@ probe end print(@hist_linear(bar, 1000, 10000, 1000)) println(@hist_log(foo)) println(@hist_linear(bar, 1000, 10000, 1000)) + print(sprint(@hist_log(foo))) + print(sprint(@hist_linear(bar, 1000, 10000, 1000))) + print(sprintln(@hist_log(foo))) + print(sprintln(@hist_linear(bar, 1000, 10000, 1000))) } diff --git a/translate.cxx b/translate.cxx index 1278a8d5..bc5d6158 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4083,6 +4083,14 @@ c_tmpcounter::visit_print_format (print_format* e) arr->indexes[i]->visit(this); } } + + // And the result for sprint[ln](@hist_*) + if (!e->print_to_stream) + { + exp_type ty = pe_string; + tmpvar res = parent->gensym(ty); + res.declare(*parent); + } } else { @@ -4145,8 +4153,18 @@ c_unparser::visit_print_format (print_format* e) o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";"; o->newline() << "goto out;"; o->newline(-1) << "} else"; - o->newline(1) << "_stp_stat_print_histogram (" << v->hist() << ", " << agg.value() << ");"; - o->indent(-1); + if (e->print_to_stream) + { + o->newline(1) << "_stp_stat_print_histogram (" << v->hist() << ", " << agg.value() << ");"; + o->indent(-1); + } + else + { + exp_type ty = pe_string; + tmpvar res = gensym (ty); + o->newline(1) << "_stp_stat_print_histogram_buf (" << res.value() << ", MAXSTRINGLEN, " << v->hist() << ", " << agg.value() << ");"; + o->newline(-1) << res.value() << ";"; + } } delete v; |