================
@@ -262,44 +357,73 @@
DependencyScanningWorkerFilesystem::getOrEmplaceSharedEntryForUID(
std::move(TEntry.Contents));
}
-const CachedFileSystemEntry *
-DependencyScanningWorkerFilesystem::findEntryByFilenameWithWriteThrough(
- StringRef Filename) {
- if (const auto *Entry = LocalCache.findEntryByFilename(Filename))
- return Entry;
- auto &Shard = SharedCache.getShardForFilename(Filename);
- if (const auto *Entry = Shard.findEntryByFilename(Filename))
- return &LocalCache.insertEntryForFilename(Filename, *Entry);
- return nullptr;
-}
-
llvm::ErrorOr<const CachedFileSystemEntry &>
DependencyScanningWorkerFilesystem::computeAndStoreResult(
StringRef OriginalFilename, StringRef FilenameForLookup) {
- llvm::ErrorOr<llvm::vfs::Status> Stat =
- getUnderlyingFS().status(OriginalFilename);
- if (!Stat) {
- const auto &Entry =
- getOrEmplaceSharedEntryForFilename(FilenameForLookup, Stat.getError());
- return insertLocalEntryForFilename(FilenameForLookup, Entry);
- }
-
- if (const auto *Entry = findSharedEntryByUID(*Stat))
- return insertLocalEntryForFilename(FilenameForLookup, *Entry);
-
- auto TEntry =
- Stat->isDirectory() ? TentativeEntry(*Stat) : readFile(OriginalFilename);
+ auto &FilenameShard = SharedCache.getShardForFilename(FilenameForLookup);
+
+ // Acquire a per-filename in-progress entry. If another worker has already
+ // produced an entry under this filename, or is currently producing one,
+ // adopt its result instead of duplicating the underlying filesystem.
+ auto FilenameSlot = FilenameShard.acquireFilenameSlot(FilenameForLookup);
+ if (FilenameSlot.Resolved)
+ return insertLocalEntryForFilename(FilenameForLookup,
+ *FilenameSlot.Resolved);
+
+ // Compute the result.
+ std::shared_ptr<DependencyScanningFilesystemSharedCache::InProgressEntry>
+ ProducerSlot = std::move(FilenameSlot.Produce);
+ const CachedFileSystemEntry *ProducedEntry = nullptr;
+ auto ComputeResult = [&]() -> llvm::ErrorOr<const CachedFileSystemEntry &> {
+ llvm::ErrorOr<llvm::vfs::Status> Stat =
+ getUnderlyingFS().status(OriginalFilename);
+ if (!Stat) {
+ const auto &Entry = getOrEmplaceSharedEntryForFilename(FilenameForLookup,
+ Stat.getError());
+ ProducedEntry = &Entry;
+ return insertLocalEntryForFilename(FilenameForLookup, Entry);
+ }
- const CachedFileSystemEntry *SharedEntry = [&]() {
- if (TEntry) {
- const auto &UIDEntry = getOrEmplaceSharedEntryForUID(std::move(*TEntry));
- return &getOrInsertSharedEntryForFilename(FilenameForLookup, UIDEntry);
+ // Acquire a per-UID producer slot to dedup concurrent readFile()
+ // calls across workers that arrived under different filenames
+ // pointing at the same on-disk file.
+ auto &UIDShard = SharedCache.getShardForUID(Stat->getUniqueID());
+ auto UIDSlot = UIDShard.acquireUIDSlot(Stat->getUniqueID());
+ const CachedFileSystemEntry *SharedEntry = nullptr;
+ if (UIDSlot.Resolved) {
+ SharedEntry = UIDSlot.Resolved;
+ } else {
+ auto TEntry = Stat->isDirectory() ? TentativeEntry(*Stat)
+ : readFile(OriginalFilename);
+ if (TEntry) {
+ SharedEntry = &getOrEmplaceSharedEntryForUID(std::move(*TEntry));
+ // Publish the UID-keyed entry to anyone waiting on this UID.
+ UIDShard.fulfilUIDSlot(Stat->getUniqueID(), UIDSlot.Produce,
+ SharedEntry);
+ } else {
+ // `readFile` failed despite `stat` succeeding. Cache
+ // the failure under the filename, and publish that same entry under
+ // the UID so that awaiting workers surface the error rather than
racing
+ // to retry the open.
+ SharedEntry = &getOrEmplaceSharedEntryForFilename(FilenameForLookup,
+ TEntry.getError());
+ UIDShard.fulfilUIDSlot(Stat->getUniqueID(), UIDSlot.Produce,
+ SharedEntry);
+ }
}
- return &getOrEmplaceSharedEntryForFilename(FilenameForLookup,
- TEntry.getError());
- }();
- return insertLocalEntryForFilename(FilenameForLookup, *SharedEntry);
+ // Bind the resolved/produced entry to this filename in the shared cache
+ // (idempotent if already there) and the local cache.
+ SharedEntry =
+ &getOrInsertSharedEntryForFilename(FilenameForLookup, *SharedEntry);
+ ProducedEntry = SharedEntry;
+ return insertLocalEntryForFilename(FilenameForLookup, *SharedEntry);
+ };
+
+ auto Result = ComputeResult();
----------------
artemcm wrote:
Done.
https://github.com/llvm/llvm-project/pull/199680
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits