From 9bd1a1619e282c585b3f202d84790f8811d1e4d6 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 10 Apr 2019 14:16:21 +0200 Subject: Always use cached mtime if available Besides other things, this is required for "logical clean" in the try-run mode to work properly: $ b -vn clean update --- build2/cc/compile-rule.cxx | 22 ++++++++++++++++++++-- build2/context.hxx | 4 +++- build2/rule.cxx | 6 +++--- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx index 3050a37..92ba32d 100644 --- a/build2/cc/compile-rule.cxx +++ b/build2/cc/compile-rule.cxx @@ -823,8 +823,22 @@ namespace build2 // compiler, options, or source file) or if the depdb is newer than // the target (interrupted update), then do unconditional update. // + // Note that load_mtime() can only be used in the execute phase so we + // have to check for a cached value manually. + // + bool u; timestamp mt; - bool u (dd.writing () || dd.mtime > (mt = mtime (tp))); + + if (dd.writing ()) + u = true; + else + { + if ((mt = t.mtime ()) == timestamp_unknown) + t.mtime (mt = mtime (tp)); // Cache. + + u = dd.mtime > mt; + } + if (u) mt = timestamp_nonexistent; // Treat as if it doesn't exist. @@ -1045,6 +1059,9 @@ namespace build2 // store the first in the target file (so we do touch it) and the // second in depdb (which is never newer that the target). // + // Perhaps when we start keeping the partially preprocessed this will + // fall away? Yes, please. + // md.mt = u ? timestamp_nonexistent : dd.mtime; } @@ -4319,10 +4336,11 @@ namespace build2 if (md.touch) { touch (tp, false, 2); + t.mtime (system_clock::now ()); skip_count.fetch_add (1, memory_order_relaxed); } + // Note: else mtime should be cached. - t.mtime (md.mt); return *pr.first; } diff --git a/build2/context.hxx b/build2/context.hxx index a8d6833..5799eef 100644 --- a/build2/context.hxx +++ b/build2/context.hxx @@ -420,7 +420,9 @@ namespace build2 // Note that for this mode to function properly we have to use fake mtimes. // Specifically, a rule that pretends to update a target must set its mtime // to system_clock::now() and everyone else must use this cached value. In - // other words, there should be no mtime re-query from the filesystem. + // other words, there should be no mtime re-query from the filesystem. The + // same is required for "logical clean" (i.e., dry-run 'clean update' in + // order to see all the command lines). // // At first, it may seem like we should also "dry-run" changes to depdb. But // that would be both problematic (some rules update it in apply() during diff --git a/build2/rule.cxx b/build2/rule.cxx index 79b91b3..a09e28b 100644 --- a/build2/rule.cxx +++ b/build2/rule.cxx @@ -55,8 +55,8 @@ namespace build2 timestamp ts (mt.mtime ()); - if (ts != timestamp_unknown && ts != timestamp_nonexistent) - return true; + if (ts != timestamp_unknown) + return ts != timestamp_nonexistent; // Otherwise, if this is not a path_target, then we don't match. // @@ -86,7 +86,7 @@ namespace build2 ts = mtime (*p); pt->mtime (ts); - if (ts != timestamp_unknown && ts != timestamp_nonexistent) + if (ts != timestamp_nonexistent) return true; l4 ([&]{trace << "no existing file for target " << *pt;}); -- cgit v1.1