aboutsummaryrefslogtreecommitdiff
path: root/build2/variable.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-12-05 17:34:00 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-12-05 17:34:00 +0200
commitfebfafcf7f0e4d1cbe878e7dfffd9c9b78036aed (patch)
tree03d9fffbc37f7a9ecf213155bfdf9d9839dfb289 /build2/variable.cxx
parente5e975934fd25811a79f3fc40ba7f94b7d1cb0b4 (diff)
Add support for first-access value typification during non-load phases
Diffstat (limited to 'build2/variable.cxx')
-rw-r--r--build2/variable.cxx49
1 files changed, 24 insertions, 25 deletions
diff --git a/build2/variable.cxx b/build2/variable.cxx
index 6eb2377..ed9527e 100644
--- a/build2/variable.cxx
+++ b/build2/variable.cxx
@@ -334,6 +334,19 @@ namespace build2
}
void
+ typify_atomic (value& v, const value_type& t, const variable* var)
+ {
+ // Typification is kind of like caching so we reuse that mutex shard.
+ //
+ shared_mutex& m (
+ variable_cache_mutex_shard[
+ hash<value*> () (&v) % variable_cache_mutex_shard_size]);
+
+ ulock l (m);
+ typify (v, t, var); // v.type is rechecked by typify(), stored under lock.
+ }
+
+ void
untypify (value& v)
{
if (v.type == nullptr)
@@ -1228,29 +1241,16 @@ namespace build2
// variable_map
//
- void variable_map::
- typify (value_data& v, const variable& var) const
- {
- // We assume typification is not modification so no version increment.
- //
- build2::typify (v, *var.type, &var);
- }
-
auto variable_map::
find (const variable& var, bool typed) const -> const value_data*
{
auto i (m_.find (var));
const value_data* r (i != m_.end () ? &i->second : nullptr);
- // First access after being assigned a type?
+ // Check if this is the first access after being assigned a type.
//
- if (r != nullptr && typed && var.type != nullptr && r->type != var.type)
- {
- // All values shall be typed during load.
- //
- assert (!global_ || phase == run_phase::load);
- typify (const_cast<value_data&> (*r), var);
- }
+ if (r != nullptr && typed && var.type != nullptr)
+ typify (*r, var);
return r;
}
@@ -1276,9 +1276,11 @@ namespace build2
if (!p.second)
{
- // First access after being assigned a type?
+ // Check if this is the first access after being assigned a type.
//
- if (typed && var.type != nullptr && r.type != var.type)
+ // Note: we still need atomic in case this is not a global state.
+ //
+ if (typed && var.type != nullptr)
typify (r, var);
}
@@ -1351,13 +1353,10 @@ namespace build2
if (const variable_map::value_data* v = vm.find (var, false))
{
- if (v->extra == 0 && var.type != nullptr && v->type != var.type)
- {
- // All values shall be typed during load.
- //
- assert (!global_ || phase == run_phase::load);
- vm.typify (const_cast<variable_map::value_data&> (*v), var);
- }
+ // Check if this is the first access after being assigned a type.
+ //
+ if (v->extra == 0 && var.type != nullptr)
+ vm.typify (*v, var);
return lookup (*v, vm);
}