aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/context.cxx98
-rw-r--r--libbuild2/context.hxx228
-rw-r--r--libbuild2/context.ixx32
3 files changed, 186 insertions, 172 deletions
diff --git a/libbuild2/context.cxx b/libbuild2/context.cxx
index d1bfc33..815a556 100644
--- a/libbuild2/context.cxx
+++ b/libbuild2/context.cxx
@@ -28,11 +28,11 @@ namespace build2
scheduler sched;
run_phase phase;
- phase_mutex phase_mutex::instance;
+ run_phase_mutex phase_mutex;
size_t load_generation;
- bool phase_mutex::
+ bool run_phase_mutex::
lock (run_phase p)
{
bool r;
@@ -83,7 +83,7 @@ namespace build2
return r;
}
- void phase_mutex::
+ void run_phase_mutex::
unlock (run_phase p)
{
// In case of load, release the exclusive access mutex.
@@ -126,7 +126,7 @@ namespace build2
}
}
- bool phase_mutex::
+ bool run_phase_mutex::
relock (run_phase o, run_phase n)
{
// Pretty much a fused unlock/lock implementation except that we always
@@ -223,9 +223,9 @@ namespace build2
assert (l->p == p);
else
{
- if (!phase_mutex::instance.lock (p))
+ if (!phase_mutex.lock (p))
{
- phase_mutex::instance.unlock (p);
+ phase_mutex.unlock (p);
throw failed ();
}
@@ -241,7 +241,7 @@ namespace build2
if (phase_lock_instance == this)
{
phase_lock_instance = nullptr;
- phase_mutex::instance.unlock (p);
+ phase_mutex.unlock (p);
//text << this_thread::get_id () << " phase release " << p;
}
@@ -256,7 +256,7 @@ namespace build2
if (u)
{
phase_lock_instance = nullptr;
- phase_mutex::instance.unlock (l->p);
+ phase_mutex.unlock (l->p);
//text << this_thread::get_id () << " phase unlock " << l->p;
}
@@ -267,7 +267,7 @@ namespace build2
{
if (l != nullptr)
{
- bool r (phase_mutex::instance.lock (l->p));
+ bool r (phase_mutex.lock (l->p));
phase_lock_instance = l;
// Fail unless we are already failing. Note that we keep the phase
@@ -286,9 +286,9 @@ namespace build2
phase_switch (run_phase n)
: o (phase), n (n)
{
- if (!phase_mutex::instance.relock (o, n))
+ if (!phase_mutex.relock (o, n))
{
- phase_mutex::instance.relock (n, o);
+ phase_mutex.relock (n, o);
throw failed ();
}
@@ -309,11 +309,11 @@ namespace build2
//
if (n == run_phase::load && uncaught_exception ())
{
- mlock l (phase_mutex::instance.m_);
- phase_mutex::instance.fail_ = true;
+ mlock l (phase_mutex.m_);
+ phase_mutex.fail_ = true;
}
- bool r (phase_mutex::instance.relock (n, o));
+ bool r (phase_mutex.relock (n, o));
phase_lock_instance->p = o;
// Similar logic to ~phase_unlock().
@@ -324,30 +324,6 @@ namespace build2
//text << this_thread::get_id () << " phase restore " << n << " " << o;
}
- const variable* var_src_root;
- const variable* var_out_root;
- const variable* var_src_base;
- const variable* var_out_base;
- const variable* var_forwarded;
-
- const variable* var_project;
- const variable* var_amalgamation;
- const variable* var_subprojects;
- const variable* var_version;
-
- const variable* var_project_url;
- const variable* var_project_summary;
-
- const variable* var_import_target;
-
- const variable* var_clean;
- const variable* var_backlink;
- const variable* var_include;
-
- const char var_extension[10] = "extension";
-
- const variable* var_build_meta_operation;
-
string current_mname;
string current_oname;
@@ -365,21 +341,15 @@ namespace build2
bool keep_going = false;
bool dry_run = false;
- void (*config_save_variable) (scope&, const variable&, uint64_t);
-
- const string& (*config_preprocess_create) (const variable_overrides&,
- values&,
- vector_view<opspec>&,
- bool,
- const location&);
-
variable_overrides
reset (const strings& cmd_vars)
{
tracer trace ("reset");
- // @@ Need to unload modules when we dynamically load them.
- //
+ // @@ Do we want to unload dynamically loaded modules? Note that this will
+ // be purely an optimization since a module could be linked-in (i.e., a
+ // module cannot expect to be unloaded/re-initialized for each meta-
+ // operation).
l6 ([&]{trace << "resetting build state";});
@@ -841,6 +811,38 @@ namespace build2
return vos;
}
+ void (*config_save_variable) (scope&, const variable&, uint64_t);
+
+ const string& (*config_preprocess_create) (const variable_overrides&,
+ values&,
+ vector_view<opspec>&,
+ bool,
+ const location&);
+
+ const variable* var_src_root;
+ const variable* var_out_root;
+ const variable* var_src_base;
+ const variable* var_out_base;
+ const variable* var_forwarded;
+
+ const variable* var_project;
+ const variable* var_amalgamation;
+ const variable* var_subprojects;
+ const variable* var_version;
+
+ const variable* var_project_url;
+ const variable* var_project_summary;
+
+ const variable* var_import_target;
+
+ const variable* var_clean;
+ const variable* var_backlink;
+ const variable* var_include;
+
+ const char var_extension[10] = "extension";
+
+ const variable* var_build_meta_operation;
+
dir_path
src_out (const dir_path& out, const scope& r)
{
diff --git a/libbuild2/context.hxx b/libbuild2/context.hxx
index f662fdd..86867a1 100644
--- a/libbuild2/context.hxx
+++ b/libbuild2/context.hxx
@@ -80,7 +80,7 @@ namespace build2
// false. Note that in this case we still switch to the desired phase. See
// the phase_{lock,switch,unlock} implementations for details.
//
- class LIBBUILD2_SYMEXPORT phase_mutex
+ class LIBBUILD2_SYMEXPORT run_phase_mutex
{
public:
// Acquire a phase lock potentially blocking (unless already in the
@@ -101,20 +101,18 @@ namespace build2
bool
relock (run_phase unlock, run_phase lock);
- private:
- friend struct phase_lock;
- friend struct phase_unlock;
- friend struct phase_switch;
-
- phase_mutex ()
+ public:
+ run_phase_mutex ()
: fail_ (false), lc_ (0), mc_ (0), ec_ (0)
{
phase = run_phase::load;
}
- static phase_mutex instance;
-
private:
+ friend struct phase_lock;
+ friend struct phase_unlock;
+ friend struct phase_switch;
+
// We have a counter for each phase which represents the number of threads
// in or waiting for this phase.
//
@@ -140,6 +138,8 @@ namespace build2
mutex lm_;
};
+ extern run_phase_mutex phase_mutex;
+
// Grab a new phase lock releasing it on destruction. The lock can be
// "owning" or "referencing" (recursive).
//
@@ -260,87 +260,6 @@ namespace build2
bool phase;
};
- // Cached variables.
- //
- // Note: consider printing in info meta-operation if adding anything here.
- //
- LIBBUILD2_SYMEXPORT extern const variable* var_src_root;
- LIBBUILD2_SYMEXPORT extern const variable* var_out_root;
- LIBBUILD2_SYMEXPORT extern const variable* var_src_base;
- LIBBUILD2_SYMEXPORT extern const variable* var_out_base;
- LIBBUILD2_SYMEXPORT extern const variable* var_forwarded;
-
- LIBBUILD2_SYMEXPORT extern const variable* var_project;
- LIBBUILD2_SYMEXPORT extern const variable* var_amalgamation;
- LIBBUILD2_SYMEXPORT extern const variable* var_subprojects;
- LIBBUILD2_SYMEXPORT extern const variable* var_version;
-
- // project.url
- //
- LIBBUILD2_SYMEXPORT extern const variable* var_project_url;
-
- // project.summary
- //
- LIBBUILD2_SYMEXPORT extern const variable* var_project_summary;
-
- // import.target
- //
- LIBBUILD2_SYMEXPORT extern const variable* var_import_target;
-
- // [bool] target visibility
- //
- LIBBUILD2_SYMEXPORT extern const variable* var_clean;
-
- // Forwarded configuration backlink mode. Valid values are:
- //
- // false - no link.
- // true - make a link using appropriate mechanism.
- // symbolic - make a symbolic link.
- // hard - make a hard link.
- // copy - make a copy.
- // overwrite - copy over but don't remove on clean (committed gen code).
- //
- // Note that it can be set by a matching rule as a rule-specific variable.
- //
- // [string] target visibility
- //
- LIBBUILD2_SYMEXPORT extern const variable* var_backlink;
-
- // Prerequisite inclusion/exclusion. Valid values are:
- //
- // false - exclude.
- // true - include.
- // adhoc - include but treat as an ad hoc input.
- //
- // If a rule uses prerequisites as inputs (as opposed to just matching them
- // with the "pass-through" semantics), then the adhoc value signals that a
- // prerequisite is an ad hoc input. A rule should match and execute such a
- // prerequisite (whether its target type is recognized as suitable input or
- // not) and assume that the rest will be handled by the user (e.g., it will
- // be passed via a command line argument or some such). Note that this
- // mechanism can be used to both treat unknown prerequisite types as inputs
- // (for example, linker scripts) as well as prevent treatment of known
- // prerequisite types as such while still matching and executing them (for
- // example, plugin libraries).
- //
- // A rule with the "pass-through" semantics should treat the adhoc value
- // the same as true.
- //
- // To query this value in rule implementations use the include() helpers
- // from <libbuild2/prerequisites.hxx>.
- //
- // [string] prereq visibility
- //
- LIBBUILD2_SYMEXPORT extern const variable* var_include;
-
- LIBBUILD2_SYMEXPORT extern const char var_extension[10]; // "extension"
-
- // The build.* namespace.
- //
- // .meta_operation
- //
- LIBBUILD2_SYMEXPORT extern const variable* var_build_meta_operation;
-
// Current action (meta/operation).
//
// The names unlike info are available during boot but may not yet be
@@ -383,37 +302,13 @@ namespace build2
LIBBUILD2_SYMEXPORT extern atomic_count target_count;
LIBBUILD2_SYMEXPORT extern atomic_count skip_count;
- inline void
- set_current_mif (const meta_operation_info& mif)
- {
- if (current_mname != mif.name)
- {
- current_mname = mif.name;
- global_scope->rw ().assign (var_build_meta_operation) = mif.name;
- }
+ void
+ set_current_mif (const meta_operation_info&);
- current_mif = &mif;
- current_on = 0; // Reset.
- }
-
- inline void
- set_current_oif (const operation_info& inner_oif,
- const operation_info* outer_oif = nullptr,
- bool diag_noise = true)
- {
- current_oname = (outer_oif == nullptr ? inner_oif : *outer_oif).name;
- current_inner_oif = &inner_oif;
- current_outer_oif = outer_oif;
- current_on++;
- current_mode = inner_oif.mode;
- current_diag_noise = diag_noise;
-
- // Reset counters (serial execution).
- //
- dependency_count.store (0, memory_order_relaxed);
- target_count.store (0, memory_order_relaxed);
- skip_count.store (0, memory_order_relaxed);
- }
+ void
+ set_current_oif (const operation_info& inner,
+ const operation_info* outer = nullptr,
+ bool diag_noise = true);
// Keep going flag.
//
@@ -456,6 +351,12 @@ namespace build2
//
LIBBUILD2_SYMEXPORT extern bool dry_run;
+ // Reset the build state. In particular, this removes all the targets,
+ // scopes, and variables.
+ //
+ LIBBUILD2_SYMEXPORT variable_overrides
+ reset (const strings& cmd_vars);
+
// Config module entry points.
//
LIBBUILD2_SYMEXPORT extern void (*config_save_variable) (
@@ -468,11 +369,90 @@ namespace build2
bool lifted,
const location&);
- // Reset the build state. In particular, this removes all the targets,
- // scopes, and variables.
+ // Cached variables.
+ //
+
+ // Note: consider printing in info meta-operation if adding anything here.
+ //
+ LIBBUILD2_SYMEXPORT extern const variable* var_src_root;
+ LIBBUILD2_SYMEXPORT extern const variable* var_out_root;
+ LIBBUILD2_SYMEXPORT extern const variable* var_src_base;
+ LIBBUILD2_SYMEXPORT extern const variable* var_out_base;
+ LIBBUILD2_SYMEXPORT extern const variable* var_forwarded;
+
+ LIBBUILD2_SYMEXPORT extern const variable* var_project;
+ LIBBUILD2_SYMEXPORT extern const variable* var_amalgamation;
+ LIBBUILD2_SYMEXPORT extern const variable* var_subprojects;
+ LIBBUILD2_SYMEXPORT extern const variable* var_version;
+
+ // project.url
+ //
+ LIBBUILD2_SYMEXPORT extern const variable* var_project_url;
+
+ // project.summary
+ //
+ LIBBUILD2_SYMEXPORT extern const variable* var_project_summary;
+
+ // import.target
+ //
+ LIBBUILD2_SYMEXPORT extern const variable* var_import_target;
+
+ // [bool] target visibility
+ //
+ LIBBUILD2_SYMEXPORT extern const variable* var_clean;
+
+ // Forwarded configuration backlink mode. Valid values are:
+ //
+ // false - no link.
+ // true - make a link using appropriate mechanism.
+ // symbolic - make a symbolic link.
+ // hard - make a hard link.
+ // copy - make a copy.
+ // overwrite - copy over but don't remove on clean (committed gen code).
+ //
+ // Note that it can be set by a matching rule as a rule-specific variable.
+ //
+ // [string] target visibility
+ //
+ LIBBUILD2_SYMEXPORT extern const variable* var_backlink;
+
+ // Prerequisite inclusion/exclusion. Valid values are:
+ //
+ // false - exclude.
+ // true - include.
+ // adhoc - include but treat as an ad hoc input.
+ //
+ // If a rule uses prerequisites as inputs (as opposed to just matching them
+ // with the "pass-through" semantics), then the adhoc value signals that a
+ // prerequisite is an ad hoc input. A rule should match and execute such a
+ // prerequisite (whether its target type is recognized as suitable input or
+ // not) and assume that the rest will be handled by the user (e.g., it will
+ // be passed via a command line argument or some such). Note that this
+ // mechanism can be used to both treat unknown prerequisite types as inputs
+ // (for example, linker scripts) as well as prevent treatment of known
+ // prerequisite types as such while still matching and executing them (for
+ // example, plugin libraries).
+ //
+ // A rule with the "pass-through" semantics should treat the adhoc value
+ // the same as true.
+ //
+ // To query this value in rule implementations use the include() helpers
+ // from <libbuild2/prerequisites.hxx>.
+ //
+ // [string] prereq visibility
+ //
+ LIBBUILD2_SYMEXPORT extern const variable* var_include;
+
+ LIBBUILD2_SYMEXPORT extern const char var_extension[10]; // "extension"
+
+ // The build.* namespace.
+ //
+ // .meta_operation
+ //
+ LIBBUILD2_SYMEXPORT extern const variable* var_build_meta_operation;
+
+ // Utility.
//
- LIBBUILD2_SYMEXPORT variable_overrides
- reset (const strings& cmd_vars);
// Return the project name or empty string if unnamed.
//
diff --git a/libbuild2/context.ixx b/libbuild2/context.ixx
index f947bd7..1364eb8 100644
--- a/libbuild2/context.ixx
+++ b/libbuild2/context.ixx
@@ -57,4 +57,36 @@ namespace build2
sched.wait (start_count, *task_count);
task_count = nullptr;
}
+
+ inline void
+ set_current_mif (const meta_operation_info& mif)
+ {
+ if (current_mname != mif.name)
+ {
+ current_mname = mif.name;
+ global_scope->rw ().assign (var_build_meta_operation) = mif.name;
+ }
+
+ current_mif = &mif;
+ current_on = 0; // Reset.
+ }
+
+ inline void
+ set_current_oif (const operation_info& inner_oif,
+ const operation_info* outer_oif,
+ bool diag_noise)
+ {
+ current_oname = (outer_oif == nullptr ? inner_oif : *outer_oif).name;
+ current_inner_oif = &inner_oif;
+ current_outer_oif = outer_oif;
+ current_on++;
+ current_mode = inner_oif.mode;
+ current_diag_noise = diag_noise;
+
+ // Reset counters (serial execution).
+ //
+ dependency_count.store (0, memory_order_relaxed);
+ target_count.store (0, memory_order_relaxed);
+ skip_count.store (0, memory_order_relaxed);
+ }
}