[Support][Cache] Make pruneCache return an Expected (#191367)
When `sys::fs::disk_space` would fail in during a call to `pruneCache`, it would report a `fatal_error`. However, a failure to prune doesn't mean the caller should fail catastrophically. Downstream, we use LLVM's cache in the OpenCL runtime. A failure to prune the cache can be safely ignored without stopping the user's application.
This commit is contained in:
1 parent
378456f49b
commit
d476ab3e85
10 files changed
+41
-18
No files matched your search
+1
-1
@@ -241,7 +241,7 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
|
||||
}
|
||||
|
||||
if (!ctx.config.ltoCache.empty())
|
||||
pruneCache(ctx.config.ltoCache, ctx.config.ltoCachePolicy, files);
|
||||
check(pruneCache(ctx.config.ltoCache, ctx.config.ltoCachePolicy, files));
|
||||
|
||||
std::vector<InputFile *> ret;
|
||||
bool emitASM = ctx.config.emit == EmitKind::ASM;
|
||||
|
||||
+2
-1
@@ -377,7 +377,8 @@ SmallVector<std::unique_ptr<InputFile>, 0> BitcodeCompiler::compile() {
|
||||
}
|
||||
|
||||
if (!ctx.arg.thinLTOCacheDir.empty())
|
||||
pruneCache(ctx.arg.thinLTOCacheDir, ctx.arg.thinLTOCachePolicy, files);
|
||||
check(
|
||||
pruneCache(ctx.arg.thinLTOCacheDir, ctx.arg.thinLTOCachePolicy, files));
|
||||
|
||||
if (!ctx.arg.ltoObjPath.empty()) {
|
||||
saveBuffer(buf[0].second, ctx.arg.ltoObjPath);
|
||||
|
||||
+2
-1
@@ -278,7 +278,8 @@ std::vector<ObjFile *> BitcodeCompiler::compile() {
|
||||
}
|
||||
|
||||
if (!config->thinLTOCacheDir.empty())
|
||||
pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy, files);
|
||||
check(
|
||||
pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy, files));
|
||||
|
||||
std::vector<ObjFile *> ret;
|
||||
for (unsigned i = 0; i < maxTasks; ++i) {
|
||||
|
||||
+2
-1
@@ -250,7 +250,8 @@ SmallVector<InputFile *, 0> BitcodeCompiler::compile() {
|
||||
}
|
||||
|
||||
if (!ctx.arg.thinLTOCacheDir.empty())
|
||||
pruneCache(ctx.arg.thinLTOCacheDir, ctx.arg.thinLTOCachePolicy, files);
|
||||
check(
|
||||
pruneCache(ctx.arg.thinLTOCacheDir, ctx.arg.thinLTOCachePolicy, files));
|
||||
|
||||
SmallVector<InputFile *, 0> ret;
|
||||
for (unsigned i = 0; i != maxTasks; ++i) {
|
||||
|
||||
@@ -46,7 +46,12 @@ llvm::CachePruningPolicy DataFileCache::GetLLDBIndexCachePolicy() {
|
||||
|
||||
DataFileCache::DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy policy) {
|
||||
m_cache_dir.SetPath(path);
|
||||
pruneCache(path, policy);
|
||||
llvm::Expected<bool> err_or_pruned = pruneCache(path, policy);
|
||||
if (!err_or_pruned) {
|
||||
Log *log = GetLog(LLDBLog::Modules);
|
||||
LLDB_LOG_ERROR(log, err_or_pruned.takeError(),
|
||||
"failed to prune lldb index cache directory: {0}");
|
||||
}
|
||||
|
||||
// This lambda will get called when the data is gotten from the cache and
|
||||
// also after the data was set for a given key. We only need to take
|
||||
|
||||
@@ -70,9 +70,11 @@ struct CachePruningPolicy {
|
||||
LLVM_ABI Expected<CachePruningPolicy>
|
||||
parseCachePruningPolicy(StringRef PolicyStr);
|
||||
|
||||
/// Peform pruning using the supplied policy, returns true if pruning
|
||||
/// Perform pruning using the supplied policy, returns true if pruning
|
||||
/// occurred, i.e. if Policy.Interval was expired.
|
||||
///
|
||||
/// On failure, it returns an Expected with the Error.
|
||||
///
|
||||
/// Check whether cache pruning happens using the supplied policy, adds a
|
||||
/// ThinLTO warning if cache_size_bytes or cache_size_files is too small for the
|
||||
/// current link job. The warning recommends the user to consider adjusting
|
||||
@@ -81,7 +83,7 @@ parseCachePruningPolicy(StringRef PolicyStr);
|
||||
/// As a safeguard against data loss if the user specifies the wrong directory
|
||||
/// as their cache directory, this function will ignore files not matching the
|
||||
/// pattern "llvmcache-*".
|
||||
LLVM_ABI bool
|
||||
LLVM_ABI Expected<bool>
|
||||
pruneCache(StringRef Path, CachePruningPolicy Policy,
|
||||
const std::vector<std::unique_ptr<MemoryBuffer>> &Files = {});
|
||||
} // namespace llvm
|
||||
|
||||
@@ -274,7 +274,13 @@ Expected<std::string> getCachedOrDownloadArtifact(
|
||||
parseCachePruningPolicy(std::getenv("DEBUGINFOD_CACHE_POLICY"));
|
||||
if (!PruningPolicyOrErr)
|
||||
return PruningPolicyOrErr.takeError();
|
||||
pruneCache(CacheDirectoryPath, *PruningPolicyOrErr);
|
||||
|
||||
Expected<bool> PrunedOrErr =
|
||||
pruneCache(CacheDirectoryPath, *PruningPolicyOrErr);
|
||||
// Log the error but continue execution: failure to prune the cache is not
|
||||
// fatal.
|
||||
if (!PrunedOrErr)
|
||||
logAllUnhandledErrors(PrunedOrErr.takeError(), WithColor::warning());
|
||||
|
||||
// Return the path to the artifact on disk.
|
||||
return std::string(AbsCachedArtifactPath);
|
||||
|
||||
@@ -1224,7 +1224,12 @@ void ThinLTOCodeGenerator::run() {
|
||||
}
|
||||
}
|
||||
|
||||
pruneCache(CacheOptions.Path, CacheOptions.Policy, ProducedBinaries);
|
||||
Expected<bool> PrunedOrErr =
|
||||
pruneCache(CacheOptions.Path, CacheOptions.Policy, ProducedBinaries);
|
||||
if (!PrunedOrErr) {
|
||||
errs() << "Error: " << toString(PrunedOrErr.takeError()) << "\n";
|
||||
report_fatal_error("ThinLTO: failure to prune cache");
|
||||
}
|
||||
|
||||
// If statistics were requested, print them out now.
|
||||
if (llvm::AreStatisticsEnabled())
|
||||
|
||||
@@ -142,8 +142,9 @@ llvm::parseCachePruningPolicy(StringRef PolicyStr) {
|
||||
}
|
||||
|
||||
/// Prune the cache of files that haven't been accessed in a long time.
|
||||
bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy,
|
||||
const std::vector<std::unique_ptr<MemoryBuffer>> &Files) {
|
||||
Expected<bool>
|
||||
llvm::pruneCache(StringRef Path, CachePruningPolicy Policy,
|
||||
const std::vector<std::unique_ptr<MemoryBuffer>> &Files) {
|
||||
using namespace std::chrono;
|
||||
|
||||
if (Path.empty())
|
||||
@@ -278,13 +279,14 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy,
|
||||
|
||||
// Prune for size now if needed
|
||||
if (Policy.MaxSizePercentageOfAvailableSpace > 0 || Policy.MaxSizeBytes > 0) {
|
||||
auto ErrOrSpaceInfo = sys::fs::disk_space(Path);
|
||||
if (!ErrOrSpaceInfo) {
|
||||
auto EC = ErrOrSpaceInfo.getError();
|
||||
report_fatal_error(Twine("Can't get available size for '") + Path.str() +
|
||||
"': " + EC.message());
|
||||
auto SpaceInfoOrErr = sys::fs::disk_space(Path);
|
||||
if (!SpaceInfoOrErr) {
|
||||
auto EC = SpaceInfoOrErr.getError();
|
||||
return createStringError(EC,
|
||||
"cannot get available disk space for '%s': '%s'",
|
||||
Path.str().c_str(), EC.message().c_str());
|
||||
}
|
||||
sys::fs::space_info SpaceInfo = ErrOrSpaceInfo.get();
|
||||
sys::fs::space_info SpaceInfo = SpaceInfoOrErr.get();
|
||||
auto AvailableSpace = TotalSize + SpaceInfo.free;
|
||||
|
||||
if (Policy.MaxSizePercentageOfAvailableSpace == 0)
|
||||
|
||||
@@ -1220,7 +1220,7 @@ static ld_plugin_status cleanup_hook(void) {
|
||||
// Prune cache
|
||||
if (!options::cache_dir.empty()) {
|
||||
CachePruningPolicy policy = check(parseCachePruningPolicy(options::cache_policy));
|
||||
pruneCache(options::cache_dir, policy);
|
||||
check(pruneCache(options::cache_dir, policy));
|
||||
}
|
||||
|
||||
return LDPS_OK;
|
||||
|
||||
Reference in new issue
Block a user