Merge pull request #4269 from obsidiansystems/sync-hash-derivation-modulo-cache

Make drv hash modulo memo table thread-safe
This commit is contained in:
Eelco Dolstra 2020-11-19 20:03:06 +01:00 committed by GitHub
commit bc4df3394d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 16 deletions

View file

@ -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 However, we don't bother doing this for floating CA derivations because
their "hash modulo" is indeterminate until built. */ their "hash modulo" is indeterminate until built. */
if (drv.type() != DerivationType::CAFloating) if (drv.type() != DerivationType::CAFloating) {
drvHashes.insert_or_assign(drvPath, auto h = hashDerivationModulo(*state.store, Derivation(drv), false);
hashDerivationModulo(*state.store, Derivation(drv), false)); drvHashes.lock()->insert_or_assign(drvPath, h);
}
state.mkAttrs(v, 1 + drv.outputs.size()); state.mkAttrs(v, 1 + drv.outputs.size());
mkString(*state.allocAttr(v, state.sDrvPath), drvPathS, {"=" + drvPathS}); mkString(*state.allocAttr(v, state.sDrvPath), drvPathS, {"=" + drvPathS});

View file

@ -451,7 +451,7 @@ DerivationType BasicDerivation::type() const
} }
DrvHashes drvHashes; Sync<DrvHashes> drvHashes;
/* pathDerivationModulo and hashDerivationModulo are mutually recursive /* pathDerivationModulo and hashDerivationModulo are mutually recursive
*/ */
@ -459,19 +459,22 @@ DrvHashes drvHashes;
/* Look up the derivation by value and memoize the /* Look up the derivation by value and memoize the
`hashDerivationModulo` call. `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()) { auto hashes = drvHashes.lock();
// Cache it auto h = hashes->find(drvPath);
h = drvHashes.insert_or_assign( if (h != hashes->end()) {
drvPath, return h->second;
hashDerivationModulo( }
store,
store.readInvalidDerivation(drvPath),
false)).first;
} }
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. /* See the header for interface details. These are the implementation details.

View file

@ -210,7 +210,8 @@ DrvHashModulo hashDerivationModulo(Store & store, const Derivation & drv, bool m
/* Memoisation of hashDerivationModulo(). */ /* Memoisation of hashDerivationModulo(). */
typedef std::map<StorePath, DrvHashModulo> DrvHashes; 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()`. */ /* Memoisation of `readDerivation(..).resove()`. */
typedef std::map< typedef std::map<