diff options
author | dsmith <dsmith> | 2006-10-23 22:09:51 +0000 |
---|---|---|
committer | dsmith <dsmith> | 2006-10-23 22:09:51 +0000 |
commit | 1b78aef5258d6681b6224c5a8e8e623449ccc11e (patch) | |
tree | 3912f9b3d5f34a8e8252e0529185441f4f8a0233 /main.cxx | |
parent | 0884d54a236c30dc2585a6b76e5846e44e54138d (diff) | |
download | systemtap-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.cxx | 192 |
1 files changed, 135 insertions, 57 deletions
@@ -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 |