diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-11-19 20:03:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-19 20:03:06 +0100 |
commit | bc4df3394db7115413c7cf6a94b44a3749b79ef7 (patch) | |
tree | 5e865ee17c08e18bb91f769a36427dbcc1d6185f | |
parent | 79aa7d95183cbe6c0d786965f0dbff414fd1aa67 (diff) | |
parent | 2113ae2d856a208350ccbafdc19e8dda322515b8 (diff) |
Merge pull request #4269 from obsidiansystems/sync-hash-derivation-modulo-cache
Make drv hash modulo memo table thread-safe
-rw-r--r-- | src/libexpr/primops.cc | 7 | ||||
-rw-r--r-- | src/libstore/derivations.cc | 27 | ||||
-rw-r--r-- | src/libstore/derivations.hh | 3 |
3 files changed, 21 insertions, 16 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 236433ef1..41f06c219 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1132,9 +1132,10 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * However, we don't bother doing this for floating CA derivations because their "hash modulo" is indeterminate until built. */ - if (drv.type() != DerivationType::CAFloating) - drvHashes.insert_or_assign(drvPath, - hashDerivationModulo(*state.store, Derivation(drv), false)); + if (drv.type() != DerivationType::CAFloating) { + auto h = hashDerivationModulo(*state.store, Derivation(drv), false); + drvHashes.lock()->insert_or_assign(drvPath, h); + } state.mkAttrs(v, 1 + drv.outputs.size()); mkString(*state.allocAttr(v, state.sDrvPath), drvPathS, {"=" + drvPathS}); diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 106ec5daa..231ca26c2 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -451,7 +451,7 @@ DerivationType BasicDerivation::type() const } -DrvHashes drvHashes; +Sync<DrvHashes> drvHashes; /* pathDerivationModulo and hashDerivationModulo are mutually recursive */ @@ -459,19 +459,22 @@ DrvHashes drvHashes; /* Look up the derivation by value and memoize the `hashDerivationModulo` call. */ -static const DrvHashModulo & pathDerivationModulo(Store & store, const StorePath & drvPath) +static const DrvHashModulo pathDerivationModulo(Store & store, const StorePath & drvPath) { - auto h = drvHashes.find(drvPath); - if (h == drvHashes.end()) { - // Cache it - h = drvHashes.insert_or_assign( - drvPath, - hashDerivationModulo( - store, - store.readInvalidDerivation(drvPath), - false)).first; + { + auto hashes = drvHashes.lock(); + auto h = hashes->find(drvPath); + if (h != hashes->end()) { + return h->second; + } } - return h->second; + auto h = hashDerivationModulo( + store, + store.readInvalidDerivation(drvPath), + false); + // Cache it + drvHashes.lock()->insert_or_assign(drvPath, h); + return h; } /* See the header for interface details. These are the implementation details. diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index f9ba935e6..b966d6d90 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -210,7 +210,8 @@ DrvHashModulo hashDerivationModulo(Store & store, const Derivation & drv, bool m /* Memoisation of hashDerivationModulo(). */ typedef std::map<StorePath, DrvHashModulo> DrvHashes; -extern DrvHashes drvHashes; // FIXME: global, not thread-safe +// FIXME: global, though at least thread-safe. +extern Sync<DrvHashes> drvHashes; /* Memoisation of `readDerivation(..).resove()`. */ typedef std::map< |