summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjistone <jistone>2006-12-09 02:03:58 +0000
committerjistone <jistone>2006-12-09 02:03:58 +0000
commit9ba8c134d15dcf75e42dfaef7f72a6bc492fdbbb (patch)
tree5def76740609ffd298ee2d558905d535a2072350
parent6a256b03673beeea1c2d6731d5b680b50778b124 (diff)
downloadsystemtap-steved-9ba8c134d15dcf75e42dfaef7f72a6bc492fdbbb.tar.gz
systemtap-steved-9ba8c134d15dcf75e42dfaef7f72a6bc492fdbbb.tar.xz
systemtap-steved-9ba8c134d15dcf75e42dfaef7f72a6bc492fdbbb.zip
2006-12-08 Josh Stone <joshua.i.stone@intel.com>
PR 3681. * staptree.h (struct vardecl): Add a literal 'init' member for the initialization value of globals. * staptree.cxx (vardecl::vardecl): Initialize 'init' to NULL. (vardecl::print): Print global init value during pass-1 output. * main.cxx (printscript): Print global init values during verbose pass-2 output. * parse.cxx (parser::parse_global): Set the initialization literal of global vardecls. * translate.cxx (var::init): Don't unconditionally override the value of numeric globals when the module_param isn't used. (c_unparser::emit_global_param): Write numeric module_params directly into the global variable, as an int64_t instead of long. (c_unparser::emit_global): Add initialization to global declarations. Don't create a temp module_param long for numeric globals anymore. runtime/ * runtime.h (param_set_int64_t, param_get_int64_t, param_check_int64_t): New functions to allow taking module parameters directly as int64_t values. testsuite/ * systemtap.base/global_init.exp, systemtap.base/global_init.stp: New test for checking the timeliness of global initialization.
-rw-r--r--ChangeLog18
-rw-r--r--main.cxx5
-rw-r--r--parse.cxx46
-rw-r--r--runtime/ChangeLog6
-rw-r--r--runtime/runtime.h31
-rw-r--r--staptree.cxx7
-rw-r--r--staptree.h2
-rw-r--r--testsuite/ChangeLog6
-rw-r--r--testsuite/systemtap.base/be_order.stp2
-rw-r--r--testsuite/systemtap.base/global_init.exp7
-rw-r--r--testsuite/systemtap.base/global_init.stp31
-rw-r--r--translate.cxx29
12 files changed, 128 insertions, 62 deletions
diff --git a/ChangeLog b/ChangeLog
index 1e94e6e4..e47b3434 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2006-12-08 Josh Stone <joshua.i.stone@intel.com>
+
+ PR 3681.
+ * staptree.h (struct vardecl): Add a literal 'init' member for the
+ initialization value of globals.
+ * staptree.cxx (vardecl::vardecl): Initialize 'init' to NULL.
+ (vardecl::print): Print global init value during pass-1 output.
+ * main.cxx (printscript): Print global init values during verbose
+ pass-2 output.
+ * parse.cxx (parser::parse_global): Set the initialization literal of
+ global vardecls.
+ * translate.cxx (var::init): Don't unconditionally override the value
+ of numeric globals when the module_param isn't used.
+ (c_unparser::emit_global_param): Write numeric module_params directly
+ into the global variable, as an int64_t instead of long.
+ (c_unparser::emit_global): Add initialization to global declarations.
+ Don't create a temp module_param long for numeric globals anymore.
+
2006-12-07 Josh Stone <joshua.i.stone@intel.com>
PR 3624.
diff --git a/main.cxx b/main.cxx
index d91f3df9..fe7e4e9e 100644
--- a/main.cxx
+++ b/main.cxx
@@ -123,6 +123,11 @@ printscript(systemtap_session& s, ostream& o)
{
vardecl* v = s.globals[i];
v->printsig (o);
+ if (s.verbose && v->init)
+ {
+ o << " = ";
+ v->init->print(o);
+ }
o << endl;
}
diff --git a/parse.cxx b/parse.cxx
index be9fd1d4..36b97dbc 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -1046,49 +1046,9 @@ parser::parse_global (vector <vardecl*>& globals, vector<probe*>& probes)
if (t && t->type == tok_operator && t->content == "=") // initialization
{
next ();
-
- // Create synthetic "begin" probe to assign value to global.
- //
- // An alternative would be to store the initializer value
- // within a new field of vardecl, and use e.g. the
- // type-resolution stage to do the rewriting. It could go
- // farther: the initializer could live through till
- // translation and be emitted as a plain C-level variable
- // initializer.
-
- literal* value = parse_literal ();
-
- probe_point* pp = new probe_point;
- probe_point::component* ppc = new probe_point::component;
- ppc->functor = string("begin");
- pp->tok = t;
- pp->components.push_back (ppc);
-
- probe* p = new probe;
- p->tok = t;
- p->locations.push_back (pp);
-
- symbol* sym = new symbol;
- sym->tok = t;
- sym->name = d->name;
-
- assignment* a = new assignment;
- a->tok = t;
- a->op = "=";
- a->left = sym;
- a->right = value;
-
- expr_statement* es = new expr_statement;
- es->tok = t;
- es->value = a;
-
- block* blk = new block;
- blk->tok = t;
- blk->statements.push_back (es);
-
- p->body = blk;
- probes.push_back (p);
-
+ d->init = parse_literal ();
+ d->set_arity(0);
+ d->type = d->init->type;
t = peek ();
}
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index 9f0c1425..69f467d1 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,9 @@
+2006-12-08 Josh Stone <joshua.i.stone@intel.com>
+
+ * runtime.h (param_set_int64_t, param_get_int64_t,
+ param_check_int64_t): New functions to allow taking module parameters
+ directly as int64_t values.
+
2006-12-06 Josh Stone <joshua.i.stone@intel.com>
* time.c (stp_timer_reregister): Add a global to control whether the
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 63b7432e..b8094451 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -1,6 +1,6 @@
/* main header file
* Copyright (C) 2005, 2006 Red Hat Inc.
- * Copyright (C) 2005 Intel Corporation.
+ * Copyright (C) 2005, 2006 Intel Corporation.
*
* This file is part of systemtap, and is free software. You can
* redistribute it and/or modify it under the terms of the GNU General
@@ -82,6 +82,35 @@ static struct
#include "perf.c"
#endif
+/* Support functions for int64_t module parameters. */
+int param_set_int64_t(const char *val, struct kernel_param *kp)
+{
+ char *endp;
+ long long ll;
+
+ if (!val)
+ return -EINVAL;
+
+ /* simple_strtoll isn't exported... */
+ if (*val == '-')
+ ll = -simple_strtoull(val+1, &endp, 0);
+ else
+ ll = simple_strtoull(val, &endp, 0);
+
+ if ((endp == val) || ((int64_t)ll != ll))
+ return -EINVAL;
+
+ *((int64_t *)kp->arg) = ll;
+ return 0;
+}
+
+int param_get_int64_t(char *buffer, struct kernel_param *kp)
+{
+ return sprintf(buffer, "%lli", (long long)*((int64_t *)kp->arg));
+}
+
+#define param_check_int64_t(name, p) __param_check(name, p, int64_t)
+
/************* Module Stuff ********************/
diff --git a/staptree.cxx b/staptree.cxx
index f3352f24..aa464469 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -104,7 +104,7 @@ probe_point::component::component (std::string const & f, literal * a):
vardecl::vardecl ():
- arity (-1)
+ arity (-1), init(NULL)
{
}
@@ -267,6 +267,11 @@ void vardecl::print (ostream& o) const
o << name;
if (arity > 0 || index_types.size() > 0)
o << "[...]";
+ if (init)
+ {
+ o << " = ";
+ init->print(o);
+ }
}
diff --git a/staptree.h b/staptree.h
index 413c65f1..8e450e48 100644
--- a/staptree.h
+++ b/staptree.h
@@ -1,5 +1,6 @@
// -*- C++ -*-
// Copyright (C) 2005, 2006 Red Hat Inc.
+// Copyright (C) 2006 Intel Corporation.
//
// This file is part of systemtap, and is free software. You can
// redistribute it and/or modify it under the terms of the GNU General
@@ -394,6 +395,7 @@ struct vardecl: public symboldecl
bool compatible_arity (int a);
int arity; // -1: unknown; 0: scalar; >0: array
std::vector<exp_type> index_types; // for arrays only
+ literal *init; // for global scalars only
};
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index 83a48057..da7929f6 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2006-12-08 Josh Stone <joshua.i.stone@intel.com>
+
+ PR 3681.
+ * systemtap.base/global_init.exp, systemtap.base/global_init.stp: New
+ test for checking the timeliness of global initialization.
+
2006-12-07 Josh Stone <joshua.i.stone@intel.com>
PR 3624.
diff --git a/testsuite/systemtap.base/be_order.stp b/testsuite/systemtap.base/be_order.stp
index eb8ef0c8..166d0dca 100644
--- a/testsuite/systemtap.base/be_order.stp
+++ b/testsuite/systemtap.base/be_order.stp
@@ -1,5 +1,5 @@
/*
- * add.stp
+ * be_order.stp
*
* Check that ordering of begin/end probes works
*/
diff --git a/testsuite/systemtap.base/global_init.exp b/testsuite/systemtap.base/global_init.exp
new file mode 100644
index 00000000..2076f20f
--- /dev/null
+++ b/testsuite/systemtap.base/global_init.exp
@@ -0,0 +1,7 @@
+# Check that global variables are initialized before all begin probes
+
+load_lib "stap_run.exp"
+
+set test "global_init"
+
+stap_run $srcdir/$subdir/$test.stp no_load $all_pass_string
diff --git a/testsuite/systemtap.base/global_init.stp b/testsuite/systemtap.base/global_init.stp
new file mode 100644
index 00000000..a5d7e58e
--- /dev/null
+++ b/testsuite/systemtap.base/global_init.stp
@@ -0,0 +1,31 @@
+/*
+ * global_init.stp
+ *
+ * Check that global variables are initialized before all begin probes
+ */
+
+probe begin { log("systemtap starting probe") }
+probe end { log("systemtap ending probe") }
+
+global gnum = 42
+global gstr = "foobar"
+
+global gnum_saved
+global gstr_saved
+probe begin(-9223372036854775808) {
+ gnum_saved = gnum
+ gstr_saved = gstr
+}
+
+probe end {
+ if (gnum_saved == 42)
+ log("systemtap test success")
+ else
+ printf("systemtap test failure - gnum_saved:%d != 42\n", gnum_saved)
+
+ if (gstr_saved == "foobar")
+ log("systemtap test success")
+ else
+ printf("systemtap test failure - gstr_saved:%s != foobar\n", gstr_saved)
+}
+
diff --git a/translate.cxx b/translate.cxx
index f6214206..d1d21ab9 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -344,7 +344,7 @@ public:
return qname() + "[0] = '\\0';";
case pe_long:
if (! local)
- return qname() + " = (int64_t) init_" + qname() + ";"; // module_param
+ return ""; // module_param
else
return qname() + " = 0;";
case pe_stats:
@@ -918,7 +918,7 @@ c_unparser::emit_global_param (vardecl *v)
if (v->arity == 0 && v->type == pe_long)
{
o->newline() << "module_param_named (" << vn << ", "
- << "init_global_" << vn << ", long, 0);";
+ << "global_" << vn << ", int64_t, 0);";
}
else if (v->arity == 0 && v->type == pe_string)
{
@@ -936,11 +936,17 @@ c_unparser::emit_global (vardecl *v)
string vn = c_varname (v->name);
if (v->arity == 0)
- o->newline() << "static __cacheline_aligned "
- << c_typename (v->type)
- << " "
- << "global_" << vn
- << ";";
+ {
+ o->newline() << "static __cacheline_aligned "
+ << c_typename (v->type)
+ << " " << "global_" << vn;
+ if (v->init)
+ {
+ o->line() << " = ";
+ v->init->visit(this);
+ }
+ o->line() << ";";
+ }
else if (v->type == pe_stats)
{
o->newline() << "static __cacheline_aligned PMAP global_"
@@ -953,15 +959,6 @@ c_unparser::emit_global (vardecl *v)
}
o->newline() << "static __cacheline_aligned rwlock_t "
<< "global_" << vn << "_lock;";
-
- // Emit module_param helper variable
- if (v->arity == 0 && v->type == pe_long)
- {
- // XXX: moduleparam.h does not have a 64-bit type, so let's just
- // take a plain long here, and manually copy/widen during
- // initialization. See var::init().
- o->newline() << "long init_global_" << vn << ";";
- }
}