summaryrefslogtreecommitdiffstats
path: root/main.cxx
diff options
context:
space:
mode:
authordsmith <dsmith>2006-10-23 22:09:51 +0000
committerdsmith <dsmith>2006-10-23 22:09:51 +0000
commit1b78aef5258d6681b6224c5a8e8e623449ccc11e (patch)
tree3912f9b3d5f34a8e8252e0529185441f4f8a0233 /main.cxx
parent0884d54a236c30dc2585a6b76e5846e44e54138d (diff)
downloadsystemtap-steved-1b78aef5258d6681b6224c5a8e8e623449ccc11e.tar.gz
systemtap-steved-1b78aef5258d6681b6224c5a8e8e623449ccc11e.tar.xz
systemtap-steved-1b78aef5258d6681b6224c5a8e8e623449ccc11e.zip
2006-10-23 David Smith <dsmith@redhat.com>
* main.cxx (printscript): New function containing code moved from main(). (main): Added code to create cache directory, call function to generate hash, and see if we can use cached source/module. If pass 4 is actually run to produce a new module, we call add_to_cache() to cache the result. * session.h (struct systemtap_session): Added hash/cache session data. * cache.cxx: New file handling adding/getting files from the cache. * cache.h: New header file for cache.cxx. * hash.cxx: New file containing C++ wrapper for routines in mdfour.c and the find_hash function which computes the hash file name for an input script. * hash.h: New header file for hash.cxx. * mdfour.c: New file containing MD4 hash code. * mdfour.h: New header file for mdfour.c. * util.cxx: New file containing several utility functions used by the caching code. * util.h: New header file for util.cxx. * Makefile.am: Added new C/C++ files. * Makefile.in: Regenerated.
Diffstat (limited to 'main.cxx')
-rw-r--r--main.cxx192
1 files changed, 135 insertions, 57 deletions
diff --git a/main.cxx b/main.cxx
index 12cca4c7..f5faf1bf 100644
--- a/main.cxx
+++ b/main.cxx
@@ -15,6 +15,9 @@
#include "translate.h"
#include "buildrun.h"
#include "session.h"
+#include "hash.h"
+#include "cache.h"
+#include "util.h"
#include <iostream>
#include <fstream>
@@ -113,6 +116,65 @@ stringify(T t)
}
+static void
+printscript(systemtap_session& s, ostream& o)
+{
+ if (s.globals.size() > 0)
+ o << "# globals" << endl;
+ for (unsigned i=0; i<s.globals.size(); i++)
+ {
+ vardecl* v = s.globals[i];
+ v->printsig (o);
+ o << endl;
+ }
+
+ if (s.functions.size() > 0)
+ o << "# functions" << endl;
+ for (unsigned i=0; i<s.functions.size(); i++)
+ {
+ functiondecl* f = s.functions[i];
+ f->printsig (o);
+ o << endl;
+ if (f->locals.size() > 0)
+ o << " # locals" << endl;
+ for (unsigned j=0; j<f->locals.size(); j++)
+ {
+ vardecl* v = f->locals[j];
+ o << " ";
+ v->printsig (o);
+ o << endl;
+ }
+ if (s.verbose)
+ {
+ f->body->print (o);
+ o << endl;
+ }
+ }
+
+ if (s.probes.size() > 0)
+ o << "# probes" << endl;
+ for (unsigned i=0; i<s.probes.size(); i++)
+ {
+ derived_probe* p = s.probes[i];
+ p->printsig (o);
+ o << endl;
+ if (p->locals.size() > 0)
+ o << " # locals" << endl;
+ for (unsigned j=0; j<p->locals.size(); j++)
+ {
+ vardecl* v = p->locals[j];
+ o << " ";
+ v->printsig (o);
+ o << endl;
+ }
+ if (s.verbose)
+ {
+ p->body->print (o);
+ o << endl;
+ }
+ }
+}
+
int
main (int argc, char * const argv [])
{
@@ -140,6 +202,7 @@ main (int argc, char * const argv [])
s.target_pid = 0;
s.merge=true;
s.perfmon=0;
+ s.use_cache = true;
const char* s_p = getenv ("SYSTEMTAP_TAPSET");
if (s_p != NULL)
@@ -159,6 +222,33 @@ main (int argc, char * const argv [])
else
s.runtime_path = string(PKGDATADIR) + "/runtime";
+ const char* s_d = getenv ("SYSTEMTAP_DIR");
+ if (s_d != NULL)
+ s.data_path = s_d;
+ else
+ s.data_path = get_home_directory() + string("/.systemtap");
+ if (create_dir(s.data_path.c_str()) == 1)
+ {
+ const char* e = strerror (errno);
+ cerr << "Warning: failed to create systemtap data directory (\""
+ << s.data_path << "\"): " << e << endl;
+ cerr << "Disabling cache support." << endl;
+ s.use_cache = false;
+ }
+
+ if (s.use_cache)
+ {
+ s.cache_path = s.data_path + "/cache";
+ if (create_dir(s.cache_path.c_str()) == 1)
+ {
+ const char* e = strerror (errno);
+ cerr << "Warning: failed to create cache directory (\""
+ << s.cache_path << "\"): " << e << endl;
+ cerr << "Disabling cache support." << endl;
+ s.use_cache = false;
+ }
+ }
+
while (true)
{
int grc = getopt (argc, argv, "hVMvtp:I:e:o:R:r:m:kgc:x:D:bs:u");
@@ -216,6 +306,8 @@ main (int argc, char * const argv [])
case 'm':
s.module_name = string (optarg);
+ cerr << "Warning: using '-m' disables cache support." << endl;
+ s.use_cache = false;
break;
case 'r':
@@ -339,6 +431,10 @@ main (int argc, char * const argv [])
clog << "Created temporary directory \"" << s.tmpdir << "\"" << endl;
}
+ // Create the name of the C source file within the temporary
+ // directory.
+ s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c";
+
struct tms tms_before;
times (& tms_before);
struct timeval tv_before;
@@ -469,62 +565,7 @@ main (int argc, char * const argv [])
rc = semantic_pass (s);
if (rc == 0 && s.last_pass == 2)
- {
- if (s.globals.size() > 0)
- cout << "# globals" << endl;
- for (unsigned i=0; i<s.globals.size(); i++)
- {
- vardecl* v = s.globals[i];
- v->printsig (cout);
- cout << endl;
- }
-
- if (s.functions.size() > 0)
- cout << "# functions" << endl;
- for (unsigned i=0; i<s.functions.size(); i++)
- {
- functiondecl* f = s.functions[i];
- f->printsig (cout);
- cout << endl;
- if (f->locals.size() > 0)
- cout << " # locals" << endl;
- for (unsigned j=0; j<f->locals.size(); j++)
- {
- vardecl* v = f->locals[j];
- cout << " ";
- v->printsig (cout);
- cout << endl;
- }
- if (s.verbose)
- {
- f->body->print (cout);
- cout << endl;
- }
- }
-
- if (s.probes.size() > 0)
- cout << "# probes" << endl;
- for (unsigned i=0; i<s.probes.size(); i++)
- {
- derived_probe* p = s.probes[i];
- p->printsig (cout);
- cout << endl;
- if (p->locals.size() > 0)
- cout << " # locals" << endl;
- for (unsigned j=0; j<p->locals.size(); j++)
- {
- vardecl* v = p->locals[j];
- cout << " ";
- v->printsig (cout);
- cout << endl;
- }
- if (s.verbose)
- {
- p->body->print (cout);
- cout << endl;
- }
- }
- }
+ printscript(s, cout);
times (& tms_after);
gettimeofday (&tv_after, NULL);
@@ -540,6 +581,38 @@ main (int argc, char * const argv [])
cerr << "Pass 2: analysis failed. "
<< "Try again with more '-v' (verbose) options."
<< endl;
+ // Generate hash. There isn't any point in generating the hash
+ // if last_pass is 2, since we'll quit before using it.
+ else if (s.last_pass != 2 && s.use_cache)
+ {
+ ostringstream o;
+ unsigned saved_verbose;
+
+ // Make sure we're in verbose mode, so that printscript()
+ // will output function/probe bodies.
+ saved_verbose = s.verbose;
+ s.verbose = 3;
+
+ // Print script to 'o'
+ printscript(s, o);
+
+ // Restore original verbose mode setting.
+ s.verbose = saved_verbose;
+
+ // Generate hash
+ find_hash (s, o.str());
+
+ // See if we can use cached source/module.
+ if (get_from_cache(s))
+ {
+ // If our last pass isn't 5, we're done (since passes 3 and
+ // 4 just generate what we just pulled out of the cache).
+ if (s.last_pass < 5) goto cleanup;
+
+ // Short-circuit to pass 5.
+ goto pass_5;
+ }
+ }
if (rc || s.last_pass == 2) goto cleanup;
@@ -548,7 +621,6 @@ main (int argc, char * const argv [])
times (& tms_before);
gettimeofday (&tv_before, NULL);
- s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c";
rc = translate_pass (s);
if (rc == 0 && s.last_pass == 3)
@@ -590,11 +662,17 @@ main (int argc, char * const argv [])
cerr << "Pass 4: compilation failed. "
<< "Try again with more '-v' (verbose) options."
<< endl;
+ else if (s.use_cache)
+ {
+ // Update cache.
+ add_to_cache(s);
+ }
// XXX: what to do if rc==0 && last_pass == 4? dump .ko file to stdout?
if (rc || s.last_pass == 4) goto cleanup;
// PASS 5: RUN
+pass_5:
times (& tms_before);
gettimeofday (&tv_before, NULL);
// NB: this message is a judgement call. The other passes don't emit