12#include "llvm/Support/AdvisoryLock.h"
13#include "llvm/Support/Chrono.h"
14#include "llvm/Support/Error.h"
15#include "llvm/Support/FileSystem.h"
16#include "llvm/Support/IOSandbox.h"
17#include "llvm/Support/MemoryBuffer.h"
18#include "llvm/Support/Path.h"
24 auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
25 for (
auto &[Path, Entry] :
Map) {
33 (void)
writeImpl(Path, Entry->Buffer->getMemBufferRef(), Size, ModTime);
39class ReaderWriterLock :
public llvm::AdvisoryLock {
41 std::optional<unsigned> OwnedGeneration;
47 std::lock_guard<std::mutex> Lock(Entry.
Mutex);
55 llvm::WaitForUnlockResult
56 waitForUnlockFor(std::chrono::seconds MaxSeconds)
override {
57 assert(!OwnedGeneration);
58 std::unique_lock<std::mutex> Lock(Entry.
Mutex);
65 return Success ? llvm::WaitForUnlockResult::Success
66 : llvm::WaitForUnlockResult::Timeout;
69 std::error_code unsafeUnlock()
override {
71 std::lock_guard<std::mutex> Lock(Entry.
Mutex);
79 ~ReaderWriterLock()
override {
80 if (OwnedGeneration) {
82 std::lock_guard<std::mutex> Lock(Entry.
Mutex);
93class InProcessModuleCache :
public ModuleCache {
94 ModuleCacheEntries &Entries;
100 InMemoryModuleCache InMemory;
102 ModuleCacheEntry &getOrCreateEntry(StringRef Filename) {
103 std::lock_guard<std::mutex> Lock(Entries.
Mutex);
104 auto &Entry = Entries.
Map[Filename];
106 Entry = std::make_unique<ModuleCacheEntry>();
111 InProcessModuleCache(ModuleCacheEntries &Entries) : Entries(Entries) {}
113 std::unique_ptr<llvm::AdvisoryLock> getLock(StringRef Filename)
override {
114 auto &Entry = getOrCreateEntry(Filename);
115 return std::make_unique<ReaderWriterLock>(Entry);
118 std::time_t getModuleTimestamp(StringRef Filename)
override {
119 auto &Timestamp = getOrCreateEntry(Filename).Timestamp;
121 return Timestamp.load();
124 void updateModuleTimestamp(StringRef Filename)
override {
126 auto &Timestamp = getOrCreateEntry(Filename).Timestamp;
128 Timestamp.store(llvm::sys::toTimeT(std::chrono::system_clock::now()));
131 void maybePrune(StringRef Path, time_t PruneInterval,
132 time_t PruneAfter)
override {
138 InMemoryModuleCache &getInMemoryModuleCache()
override {
return InMemory; }
139 const InMemoryModuleCache &getInMemoryModuleCache()
const override {
143 std::error_code write(StringRef Path, llvm::MemoryBufferRef Buffer,
144 off_t &Size, time_t &ModTime)
override {
145 ModuleCacheEntry &Entry = getOrCreateEntry(Path);
146 std::lock_guard<std::mutex> Lock(Entry.
Mutex);
149 "Wrote the same PCM with different contents");
155 llvm::MemoryBuffer::getMemBufferCopy(Buffer.getBuffer(), Path);
156 Entry.
ModTime = llvm::sys::toTimeT(std::chrono::system_clock::now());
163 Expected<std::unique_ptr<llvm::MemoryBuffer>>
164 read(StringRef
FileName, off_t &Size, time_t &ModTime)
override {
165 ModuleCacheEntry &Entry = getOrCreateEntry(
FileName);
166 std::lock_guard<std::mutex> Lock(Entry.
Mutex);
169 auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
174 return ReadBuffer.takeError();
175 Entry.
Buffer = std::move(*ReadBuffer);
181 return llvm::MemoryBuffer::getMemBuffer(*Entry.
Buffer);
186std::shared_ptr<ModuleCache>
188 return std::make_shared<InProcessModuleCache>(Entries);
std::shared_ptr< ModuleCache > makeInProcessModuleCache(ModuleCacheEntries &Entries)
The JSON file list parser is used to communicate input to InstallAPI.
Expected< std::unique_ptr< llvm::MemoryBuffer > > readImpl(StringRef FileName, off_t &Size, time_t &ModTime)
Shared implementation of ModuleCache::read().
@ Success
Annotation was successful.
void maybePruneImpl(StringRef Path, time_t PruneInterval, time_t PruneAfter, bool PruneTopLevel=false)
Shared implementation of ModuleCache::maybePrune().
std::error_code writeImpl(StringRef Path, llvm::MemoryBufferRef Buffer, off_t &Size, time_t &ModTime)
Shared implementation of ModuleCache::write().
llvm::StringMap< std::unique_ptr< ModuleCacheEntry > > Map
void flush()
Flushes all PCMs built in-process to disk.
enum clang::dependencies::ModuleCacheEntry::@010254116217305143125116322142262271134241253225 State
std::condition_variable CondVar
std::unique_ptr< llvm::MemoryBuffer > Buffer
The buffer that we've either read from disk or written in-process.
time_t ModTime
The modification time of the entry.