aboutsummaryrefslogtreecommitdiff
path: root/build2/variable
diff options
context:
space:
mode:
Diffstat (limited to 'build2/variable')
-rw-r--r--build2/variable107
1 files changed, 58 insertions, 49 deletions
diff --git a/build2/variable b/build2/variable
index 35530ca..10f4ac9 100644
--- a/build2/variable
+++ b/build2/variable
@@ -1036,7 +1036,7 @@ namespace build2
using value::value;
using value::operator=;
- size_t version = 0; // Incremented on each modification (override cache).
+ size_t version = 0; // Incremented on each modification (variable_cache).
size_t generation; // load_generation of this value (global state only).
};
@@ -1167,6 +1167,57 @@ namespace build2
map_type m_;
};
+ // Value caching. Used for overrides as well as target type/pattern-specific
+ // append/prepend.
+ //
+ // In many places we assume that we can store a reference to the returned
+ // variable value (e.g., install::lookup_install()). As a result, in these
+ // cases where we calculate the value dynamically, we have to cache it
+ // (note, however, that if the value becomes stale, there is no guarantee
+ // the references remain valid).
+ //
+ // Note that since the cache can be modified on any lookup (including during
+ // the execute phase), it is protected by its own mutex shard (allocated in
+ // main()).
+ //
+ extern size_t variable_cache_mutex_shard_size;
+ extern unique_ptr<shared_mutex[]> variable_cache_mutex_shard;
+
+ template <typename K>
+ class variable_cache
+ {
+ public:
+ // If the returned unique lock is locked, then the value has been
+ // invalidated.
+ //
+ pair<value&, ulock>
+ insert (K, const lookup& stem, size_t version);
+
+ private:
+ struct entry_type
+ {
+ // Note: we use value_data instead of value since the result is often
+ // returned as lookup. We also maintain the version in case one cached
+ // value (e.g., override) is based on another (e.g., target
+ // type/pattern-specific prepend/append).
+ //
+ variable_map::value_data value;
+
+ size_t version = 0; // Version on which this value is based.
+
+ // Location of the stem as well as the version on which this cache
+ // value is based. Used to track the location and value of the stem
+ // for cache invalidation. NULL/0 means there is no stem.
+ //
+ const variable_map* stem_vars = nullptr;
+ size_t stem_version = 0;
+ };
+
+ using map_type = std::map<K, entry_type>;
+
+ map_type m_;
+ };
+
// Target type/pattern-specific variables.
//
class variable_pattern_map
@@ -1219,65 +1270,23 @@ namespace build2
lookup
find (const target_type&, const string& tname, const variable&) const;
-
+ // Prepend/append value cache.
//
// The key is the combination of the "original value identity" (as a
// pointer to the value in one of the variable_pattern_map's) and the
// "target identity" (as target type and target name). Note that while at
// first it may seem like we don't need the target identity, we actually
- // do since the stem may itself be target-type/pattern-specific.
- //
- // @@ MT
+ // do since the stem may itself be target-type/pattern-specific. See
+ // scope::find_original() for details.
//
- mutable std::map<tuple<const value*, const target_type*, string>,
- variable_map::value_data> cache;
+ mutable
+ variable_cache<tuple<const value*, const target_type*, string>>
+ cache;
private:
bool global_;
map_type map_;
};
-
- // Value caching. Used for overrides as well as target type/pattern-specific
- // append/prepend.
- //
- // In many places we assume that we can store a reference to the returned
- // variable value (e.g., install::lookup_install()). As a result, in these
- // cases where we calculate the value dynamically, we have to cache it
- // (note, however, that if the value becomes stale, there is no guarantee
- // the references remain valid).
- //
- template <typename K>
- class variable_cache
- {
- public:
- // If the returned unique lock is locked, then the value has been
- // invalidated.
- //
- pair<value&, ulock>
- insert (K, const lookup& stem);
-
- private:
- struct entry_type
- {
- build2::value value;
-
- // Location of the stem as well as the version on which this cache
- // value is based. Used to track the location and value of the stem
- // for cache invalidation. NULL/0 means there is no stem.
- //
- const variable_map* stem_vars = nullptr;
- size_t stem_version = 0;
- };
-
- using map_type = std::map<K, entry_type>;
-
- map_type m_;
- };
-
- // Allocated in main().
- //
- extern size_t variable_cache_mutex_shard_size;
- extern unique_ptr<shared_mutex[]> variable_cache_mutex_shard;
}
#include <build2/variable.ixx>