Skip to content

Commit

Permalink
Merge pull request NixOS#4269 from obsidiansystems/sync-hash-derivati…
Browse files Browse the repository at this point in the history
…on-modulo-cache

Make drv hash modulo memo table thread-safe
  • Loading branch information
edolstra authored Nov 19, 2020
2 parents 79aa7d9 + 2113ae2 commit bc4df33
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 16 deletions.
7 changes: 4 additions & 3 deletions src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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});
Expand Down
27 changes: 15 additions & 12 deletions src/libstore/derivations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -451,27 +451,30 @@ DerivationType BasicDerivation::type() const
}


DrvHashes drvHashes;
Sync<DrvHashes> drvHashes;

/* pathDerivationModulo and hashDerivationModulo are mutually recursive
*/

/* 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.
Expand Down
3 changes: 2 additions & 1 deletion src/libstore/derivations.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand Down

0 comments on commit bc4df33

Please sign in to comment.