diff options
Diffstat (limited to 'libbuild2')
-rw-r--r-- | libbuild2/context.cxx | 98 | ||||
-rw-r--r-- | libbuild2/context.hxx | 228 | ||||
-rw-r--r-- | libbuild2/context.ixx | 32 |
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); + } } |