From 5c54d49ebb4da71680cb45e3be221e11b9b8d364 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 6 Feb 2009 14:13:51 -0800 Subject: Save kernel autoconf options in a cache file We're getting enough autoconf tests now that it's a significant chunk of the build time. Adding this cache shaves several seconds off for me. * hash.cxx (find_hash): Compute a separate script-independent hash for caching autoconf values, saved in session.stapconf_path. * buildrun.cxx (compile_pass): Tweak the Makefile to read/save the autoconf values in the cache directory --- ChangeLog | 7 +++ buildrun.cxx | 54 ++++++++++++++------- hash.cxx | 154 ++++++++++++++++++++++++++++++++++++++--------------------- session.h | 1 + 4 files changed, 143 insertions(+), 73 deletions(-) diff --git a/ChangeLog b/ChangeLog index b411c49e..9a3c3060 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-02-06 Josh Stone + + * hash.cxx (find_hash): Compute a separate script-independent hash + for caching autoconf values, saved in session.stapconf_path. + * buildrun.cxx (compile_pass): Tweak the Makefile to read/save + the autoconf values in the cache directory + 2009-02-06 Frank Ch. Eigler * buildrun.cxx: Add STAPCONF_PROCFS_OWNER test. diff --git a/buildrun.cxx b/buildrun.cxx index 69cd6afb..5b4db922 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -106,31 +106,49 @@ compile_pass (systemtap_session& s) // o << module_cflags << " += -Iusr/include" << endl; // since such headers are cleansed of _KERNEL_ pieces that we need - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-hrtimer-rel.c, -DSTAPCONF_HRTIMER_REL,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-hrtimer-getset-expires.c, -DSTAPCONF_HRTIMER_GETSET_EXPIRES,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-inode-private.c, -DSTAPCONF_INODE_PRIVATE,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-constant-tsc.c, -DSTAPCONF_CONSTANT_TSC,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-tsc-khz.c, -DSTAPCONF_TSC_KHZ,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-ktime-get-real.c, -DSTAPCONF_KTIME_GET_REAL,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-x86-uniregs.c, -DSTAPCONF_X86_UNIREGS,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-nameidata.c, -DSTAPCONF_NAMEIDATA_CLEANUP,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-unregister-kprobes.c, -DSTAPCONF_UNREGISTER_KPROBES,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-real-parent.c, -DSTAPCONF_REAL_PARENT,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-uaccess.c, -DSTAPCONF_LINUX_UACCESS_H,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-oneachcpu-retry.c, -DSTAPCONF_ONEACHCPU_RETRY,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-dpath-path.c, -DSTAPCONF_DPATH_PATH,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-synchronize-sched.c, -DSTAPCONF_SYNCHRONIZE_SCHED,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-task-uid.c, -DSTAPCONF_TASK_UID,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-vm-area.c, -DSTAPCONF_VM_AREA,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-procfs-owner.c, -DSTAPCONF_PROCFS_OWNER,)" << endl; + string stapconf_cflags = "STAPCONF_CFLAGS"; + o << stapconf_cflags << " :=" << endl; + + if (s.use_cache) + { + o << "STAPCONF_CACHE_FILE = " << s.stapconf_path << endl; + o << stapconf_cflags << " += $(shell cat $(STAPCONF_CACHE_FILE) 2>/dev/null)" << endl; + o << "ifeq (,$(strip $(" << stapconf_cflags << ")))" << endl; + } + + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-hrtimer-rel.c, -DSTAPCONF_HRTIMER_REL,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-hrtimer-getset-expires.c, -DSTAPCONF_HRTIMER_GETSET_EXPIRES,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-inode-private.c, -DSTAPCONF_INODE_PRIVATE,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-constant-tsc.c, -DSTAPCONF_CONSTANT_TSC,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-tsc-khz.c, -DSTAPCONF_TSC_KHZ,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-ktime-get-real.c, -DSTAPCONF_KTIME_GET_REAL,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-x86-uniregs.c, -DSTAPCONF_X86_UNIREGS,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-nameidata.c, -DSTAPCONF_NAMEIDATA_CLEANUP,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-unregister-kprobes.c, -DSTAPCONF_UNREGISTER_KPROBES,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-real-parent.c, -DSTAPCONF_REAL_PARENT,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-uaccess.c, -DSTAPCONF_LINUX_UACCESS_H,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-oneachcpu-retry.c, -DSTAPCONF_ONEACHCPU_RETRY,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-dpath-path.c, -DSTAPCONF_DPATH_PATH,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-synchronize-sched.c, -DSTAPCONF_SYNCHRONIZE_SCHED,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-task-uid.c, -DSTAPCONF_TASK_UID,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-vm-area.c, -DSTAPCONF_VM_AREA,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-procfs-owner.c, -DSTAPCONF_PROCFS_OWNER,)" << endl; #if 0 /* NB: For now, the performance hit of probe_kernel_read/write (vs. our * homegrown safe-access functions) is deemed undesireable, so we'll skip * this autoconf. */ - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-probe-kernel.c, -DSTAPCONF_PROBE_KERNEL,)" << endl; + o << stapconf_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-probe-kernel.c, -DSTAPCONF_PROBE_KERNEL,)" << endl; #endif + if (s.use_cache) + { + o << "$(shell echo $(" << stapconf_cflags << ") > $(STAPCONF_CACHE_FILE))" << endl; + o << "endif" << endl; + } + + o << module_cflags << " += $(" << stapconf_cflags << ")" << endl; + for (unsigned i=0; i 8) nlevels = 8; } + hashdir = s.cache_path; + + for (int i = 0; i < nlevels; i++) + { + hashdir += string("/") + result[i*2] + result[i*2 + 1]; + if (create_dir(hashdir.c_str()) != 0) + { + if (! s.suppress_warnings) + cerr << "Warning: failed to create cache directory (\"" + << hashdir + "\"): " << strerror(errno) + << ", disabling cache support." << endl; + s.use_cache = false; + return false; + } + } + return true; +} + + +static void +find_script_hash (systemtap_session& s, const string& script, const hash &base) +{ + hash h(base); + struct stat st; + // Hash getuid. This really shouldn't be necessary (since who you // are doesn't change the generated output), but the hash gets used // as the module name. If two different users try to run the same @@ -88,11 +149,6 @@ find_hash (systemtap_session& s, const string& script) // module name. h.add(getuid()); - // Hash kernel release and arch. - h.add(s.kernel_release); - h.add(s.kernel_build_tree); - h.add(s.architecture); - // Hash user-specified arguments (that change the generated module). h.add(s.bulk_mode); // '-b' h.add(s.merge); // '-M' @@ -123,53 +179,14 @@ find_hash (systemtap_session& s, const string& script) h.add(*it); // XXX: a build-id of each module might be even better - // Hash runtime path (that gets added in as "-R path"). - h.add(s.runtime_path); - - // Hash compiler path, size, and mtime. We're just going to assume - // we'll be using gcc. XXX: getting kbuild to spit out out would be - // better. - string gcc_path = find_executable ("gcc"); - if (stat(gcc_path.c_str(), &st) == 0) - { - h.add(gcc_path); - h.add(st.st_size); - h.add(st.st_mtime); - } - - // Hash the systemtap size and mtime. We could use VERSION/DATE, - // but when developing systemtap that doesn't work well (since you - // can compile systemtap multiple times in 1 day). Since we don't - // know exactly where we're getting run from, we'll use - // /proc/self/exe. - if (stat("/proc/self/exe", &st) == 0) - { - h.add(st.st_size); - h.add(st.st_mtime); - } - // Add in pass 2 script output. h.add(script); - // Use a N level subdir for the cache path to reduce the impact on - // filesystems which are slow for large directories. - string hashdir = s.cache_path; - string result; + // Get the directory path to store our cached script + string result, hashdir; h.result(result); - - for (int i = 0; i < nlevels; i++) - { - hashdir += string("/") + result[i*2] + result[i*2 + 1]; - if (create_dir(hashdir.c_str()) != 0) - { - if (! s.suppress_warnings) - cerr << "Warning: failed to create cache directory (\"" - << hashdir + "\"): " << strerror(errno) - << ", disabling cache support." << endl; - s.use_cache = false; - return; - } - } + if (!create_hashdir(s, result, hashdir)) + return; // Update module name to be 'stap_{hash start}'. '{hash start}' // must not be too long. This shouldn't happen, since the maximum @@ -192,4 +209,31 @@ find_hash (systemtap_session& s, const string& script) s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c"; } + +static void +find_stapconf_hash (systemtap_session& s, const hash& base) +{ + hash h(base); + + // The basic hash should be good enough for STAPCONF variables + + // Get the directory path to store our cached stapconf parameters + string result, hashdir; + h.result(result); + if (!create_hashdir(s, result, hashdir)) + return; + + s.stapconf_path = hashdir + "/stapconf_" + result; +} + + +void +find_hash (systemtap_session& s, const string& script) +{ + hash base; + get_base_hash(s, base); + find_stapconf_hash(s, base); + find_script_hash(s, script, base); +} + /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ diff --git a/session.h b/session.h index 9a28c936..c55310d3 100644 --- a/session.h +++ b/session.h @@ -112,6 +112,7 @@ struct systemtap_session bool use_cache; std::string cache_path; std::string hash_path; + std::string stapconf_path; // dwarfless operation bool consult_symtab; -- cgit