Skip to content

Commit f5a0e14

Browse files
committed
LocalStore::State: Put behind a ref to reduce false sharing
1 parent 66e03c2 commit f5a0e14

3 files changed

Lines changed: 25 additions & 37 deletions

File tree

src/libstore/gc.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ void LocalStore::autoGC(bool sync)
936936
std::shared_future<void> future;
937937

938938
{
939-
auto state(_state.lock());
939+
auto state(_state->lock());
940940

941941
if (state->gcRunning) {
942942
future = state->gcFuture;
@@ -969,7 +969,7 @@ void LocalStore::autoGC(bool sync)
969969

970970
/* Wake up any threads waiting for the auto-GC to finish. */
971971
Finally wakeup([&]() {
972-
auto state(_state.lock());
972+
auto state(_state->lock());
973973
state->gcRunning = false;
974974
state->lastGCCheck = std::chrono::steady_clock::now();
975975
promise.set_value();
@@ -984,7 +984,7 @@ void LocalStore::autoGC(bool sync)
984984

985985
collectGarbage(options, results);
986986

987-
_state.lock()->availAfterGC = getAvail();
987+
_state->lock()->availAfterGC = getAvail();
988988

989989
} catch (...) {
990990
// FIXME: we could propagate the exception to the

src/libstore/include/nix/store/local-store.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ private:
174174
std::unique_ptr<PublicKeys> publicKeys;
175175
};
176176

177-
Sync<State> _state;
177+
ref<Sync<State>> _state;
178178

179179
public:
180180

src/libstore/local-store.cc

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,15 @@ LocalStore::LocalStore(ref<const Config> config)
118118
: Store{*config}
119119
, LocalFSStore{*config}
120120
, config{config}
121+
, _state(make_ref<Sync<State>>())
121122
, dbDir(config->stateDir + "/db")
122123
, linksDir(config->realStoreDir + "/.links")
123124
, reservedPath(dbDir + "/reserved")
124125
, schemaPath(dbDir + "/schema")
125126
, tempRootsDir(config->stateDir + "/temproots")
126127
, fnTempRoots(fmt("%s/%d", tempRootsDir, getpid()))
127128
{
128-
auto state(_state.lock());
129+
auto state(_state->lock());
129130
state->stmts = std::make_unique<State::Stmts>();
130131

131132
/* Create missing state directories if they don't already exist. */
@@ -433,7 +434,7 @@ LocalStore::~LocalStore()
433434
std::shared_future<void> future;
434435

435436
{
436-
auto state(_state.lock());
437+
auto state(_state->lock());
437438
if (state->gcRunning)
438439
future = state->gcFuture;
439440
}
@@ -624,7 +625,7 @@ void LocalStore::registerDrvOutput(const Realisation & info)
624625
{
625626
experimentalFeatureSettings.require(Xp::CaDerivations);
626627
retrySQLite<void>([&]() {
627-
auto state(_state.lock());
628+
auto state(_state->lock());
628629
if (auto oldR = queryRealisation_(*state, info.id)) {
629630
if (info.isCompatibleWith(*oldR)) {
630631
auto combinedSignatures = oldR->signatures;
@@ -727,8 +728,7 @@ void LocalStore::queryPathInfoUncached(
727728
{
728729
try {
729730
callback(retrySQLite<std::shared_ptr<const ValidPathInfo>>([&]() {
730-
auto state(_state.lock());
731-
return queryPathInfoInternal(*state, path);
731+
return queryPathInfoInternal(*_state->lock(), path);
732732
}));
733733

734734
} catch (...) {
@@ -810,10 +810,7 @@ bool LocalStore::isValidPath_(State & state, const StorePath & path)
810810

811811
bool LocalStore::isValidPathUncached(const StorePath & path)
812812
{
813-
return retrySQLite<bool>([&]() {
814-
auto state(_state.lock());
815-
return isValidPath_(*state, path);
816-
});
813+
return retrySQLite<bool>([&]() { return isValidPath_(*_state->lock(), path); });
817814
}
818815

819816
StorePathSet LocalStore::queryValidPaths(const StorePathSet & paths, SubstituteFlag maybeSubstitute)
@@ -828,7 +825,7 @@ StorePathSet LocalStore::queryValidPaths(const StorePathSet & paths, SubstituteF
828825
StorePathSet LocalStore::queryAllValidPaths()
829826
{
830827
return retrySQLite<StorePathSet>([&]() {
831-
auto state(_state.lock());
828+
auto state(_state->lock());
832829
auto use(state->stmts->QueryValidPaths.use());
833830
StorePathSet res;
834831
while (use.next())
@@ -847,16 +844,13 @@ void LocalStore::queryReferrers(State & state, const StorePath & path, StorePath
847844

848845
void LocalStore::queryReferrers(const StorePath & path, StorePathSet & referrers)
849846
{
850-
return retrySQLite<void>([&]() {
851-
auto state(_state.lock());
852-
queryReferrers(*state, path, referrers);
853-
});
847+
return retrySQLite<void>([&]() { queryReferrers(*_state->lock(), path, referrers); });
854848
}
855849

856850
StorePathSet LocalStore::queryValidDerivers(const StorePath & path)
857851
{
858852
return retrySQLite<StorePathSet>([&]() {
859-
auto state(_state.lock());
853+
auto state(_state->lock());
860854

861855
auto useQueryValidDerivers(state->stmts->QueryValidDerivers.use()(printStorePath(path)));
862856

@@ -872,7 +866,7 @@ std::map<std::string, std::optional<StorePath>>
872866
LocalStore::queryStaticPartialDerivationOutputMap(const StorePath & path)
873867
{
874868
return retrySQLite<std::map<std::string, std::optional<StorePath>>>([&]() {
875-
auto state(_state.lock());
869+
auto state(_state->lock());
876870
std::map<std::string, std::optional<StorePath>> outputs;
877871
uint64_t drvId;
878872
drvId = queryValidPathId(*state, path);
@@ -892,7 +886,7 @@ std::optional<StorePath> LocalStore::queryPathFromHashPart(const std::string & h
892886
Path prefix = storeDir + "/" + hashPart;
893887

894888
return retrySQLite<std::optional<StorePath>>([&]() -> std::optional<StorePath> {
895-
auto state(_state.lock());
889+
auto state(_state->lock());
896890

897891
auto useQueryPathFromHashPart(state->stmts->QueryPathFromHashPart.use()(prefix));
898892

@@ -957,7 +951,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
957951
#endif
958952

959953
return retrySQLite<void>([&]() {
960-
auto state(_state.lock());
954+
auto state(_state->lock());
961955

962956
SQLiteTxn txn(state->db);
963957
StorePathSet paths;
@@ -1021,7 +1015,7 @@ void LocalStore::invalidatePath(State & state, const StorePath & path)
10211015

10221016
const PublicKeys & LocalStore::getPublicKeys()
10231017
{
1024-
auto state(_state.lock());
1018+
auto state(_state->lock());
10251019
if (!state->publicKeys)
10261020
state->publicKeys = std::make_unique<PublicKeys>(getDefaultPublicKeys());
10271021
return *state->publicKeys;
@@ -1344,7 +1338,7 @@ std::pair<std::filesystem::path, AutoCloseFD> LocalStore::createTempDirInStore()
13441338
void LocalStore::invalidatePathChecked(const StorePath & path)
13451339
{
13461340
retrySQLite<void>([&]() {
1347-
auto state(_state.lock());
1341+
auto state(_state->lock());
13481342

13491343
SQLiteTxn txn(state->db);
13501344

@@ -1444,10 +1438,8 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
14441438
update = true;
14451439
}
14461440

1447-
if (update) {
1448-
auto state(_state.lock());
1449-
updatePathInfo(*state, *info);
1450-
}
1441+
if (update)
1442+
updatePathInfo(*_state->lock(), *info);
14511443
}
14521444

14531445
} catch (Error & e) {
@@ -1534,8 +1526,7 @@ void LocalStore::verifyPath(
15341526

15351527
if (canInvalidate) {
15361528
printInfo("path '%s' disappeared, removing from database...", pathS);
1537-
auto state(_state.lock());
1538-
invalidatePath(*state, path);
1529+
invalidatePath(*_state->lock(), path);
15391530
} else {
15401531
printError("path '%s' disappeared, but it still has valid referrers!", pathS);
15411532
if (repair)
@@ -1567,14 +1558,13 @@ std::optional<TrustedFlag> LocalStore::isTrustedClient()
15671558

15681559
void LocalStore::vacuumDB()
15691560
{
1570-
auto state(_state.lock());
1571-
state->db.exec("vacuum");
1561+
_state->lock()->db.exec("vacuum");
15721562
}
15731563

15741564
void LocalStore::addSignatures(const StorePath & storePath, const StringSet & sigs)
15751565
{
15761566
retrySQLite<void>([&]() {
1577-
auto state(_state.lock());
1567+
auto state(_state->lock());
15781568

15791569
SQLiteTxn txn(state->db);
15801570

@@ -1636,10 +1626,8 @@ void LocalStore::queryRealisationUncached(
16361626
const DrvOutput & id, Callback<std::shared_ptr<const Realisation>> callback) noexcept
16371627
{
16381628
try {
1639-
auto maybeRealisation = retrySQLite<std::optional<const Realisation>>([&]() {
1640-
auto state(_state.lock());
1641-
return queryRealisation_(*state, id);
1642-
});
1629+
auto maybeRealisation =
1630+
retrySQLite<std::optional<const Realisation>>([&]() { return queryRealisation_(*_state->lock(), id); });
16431631
if (maybeRealisation)
16441632
callback(std::make_shared<const Realisation>(maybeRealisation.value()));
16451633
else

0 commit comments

Comments
 (0)