aboutsummaryrefslogtreecommitdiff
path: root/build2/context
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-01-27 15:25:26 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-02-13 12:42:41 +0200
commitf93038fbee1631b95922b0742e0fd00fa8dae02e (patch)
tree6fe67cbde528ee8ded490085b9a8d5adc0ce5aca /build2/context
parent267d34d2800d9cc3ed2865cbecf8d32f8f1ab6ec (diff)
Add notion of phase, enforce
Diffstat (limited to 'build2/context')
-rw-r--r--build2/context44
1 files changed, 40 insertions, 4 deletions
diff --git a/build2/context b/build2/context
index 7f533ca..cf5483e 100644
--- a/build2/context
+++ b/build2/context
@@ -14,14 +14,43 @@
namespace build2
{
- // Top-level model (internal state) mutex and its per-thread shared lock.
+ // In order to perform each operation the build system goes through the
+ // following phases:
//
- // - model_lock is NULL during serial execution, all changes are a go
- // - model_lock is not NULL during parallel execution, append-only changes
- // - parallel execution starts with a shared lock by creating model_slock
+ // load - load the buildfiles
+ // search & match - search prerequisites and match rules
+ // execute - execute the matched rule
+ //
+ // The phase can only be changed during serial or exclusive execution
+ // (see below).
+ //
+ extern enum class run_phase {load, search_match, execute} phase;
+
+ // The build system model (internal state) is protected at the top level by
+ // the model mutex. During serial execution the model mutex is unlocked.
//
extern shared_mutex model;
+ // Parallel execution always starts with acquiring a shared model lock (by
+ // creating model_slock; see below). Pointers to these locks are cached in
+ // the model_lock TLS variable (which is NULL during serial execution).
+ //
+ // The build system starts with a "serial load" phase and then continues
+ // with parallel search & match and execute. Search & match, however, can be
+ // interrupted with an "exclusive load" by re-locking the shared lock as
+ // exclusive, changing the phase, and loading additional buildfiles.
+ //
+ // Serial load can perform arbitrary changes to the model. Exclusive load,
+ // however, can only perform "pure appends". That is, it can create new
+ // "nodes" (variables, scopes, etc) but not change already existing nodes
+ // or invalidate any references to such (the idea here is that one should
+ // be able to load additional buildfiles as long as they don't interfere
+ // with the existing build state).
+ //
+ // @@ MT: do we really have to hold shared lock during execute?
+ // @@ MT: we can also interrupt load s&m with execute -- neither handled
+ // nor documented.
+ //
extern
#ifdef __cpp_thread_local
thread_local
@@ -30,6 +59,13 @@ namespace build2
#endif
slock* model_lock;
+ struct phase_guard
+ {
+ explicit phase_guard (run_phase p): o (phase) {phase = p;}
+ ~phase_guard () {phase = o;}
+ run_phase o;
+ };
+
// A shared model lock. If there is already an instance of model_slock in
// this thread, then the new instance simply references it (asserting that
// it is locked).