diff options
author | Håvard Pettersen <havardpe@oath.com> | 2020-06-13 10:58:10 +0000 |
---|---|---|
committer | Håvard Pettersen <havardpe@oath.com> | 2020-06-13 10:58:10 +0000 |
commit | 9b52a7496663f66cbb1310ee7ebbd931ce2e04a8 (patch) | |
tree | aa25b257c0f248c5ca0795255e4b220e606d5419 /eval | |
parent | 9b2ebf004a4c57090bd4d55ed4c660443a7fa446 (diff) |
use separate locks for result value propagation
... to avoid deadlock when using blocking executors
Diffstat (limited to 'eval')
-rw-r--r-- | eval/src/vespa/eval/eval/llvm/compile_cache.cpp | 8 | ||||
-rw-r--r-- | eval/src/vespa/eval/eval/llvm/compile_cache.h | 3 |
2 files changed, 6 insertions, 5 deletions
diff --git a/eval/src/vespa/eval/eval/llvm/compile_cache.cpp b/eval/src/vespa/eval/eval/llvm/compile_cache.cpp index 4aa18d3bb65..41106651024 100644 --- a/eval/src/vespa/eval/eval/llvm/compile_cache.cpp +++ b/eval/src/vespa/eval/eval/llvm/compile_cache.cpp @@ -15,7 +15,7 @@ std::vector<std::pair<uint64_t,Executor*>> CompileCache::_executor_stack{}; const CompiledFunction & CompileCache::Value::wait_for_result() { - std::unique_lock<std::mutex> guard(_lock); + std::unique_lock<std::mutex> guard(result_lock); cond.wait(guard, [this](){ return bool(compiled_function); }); return *compiled_function; } @@ -84,7 +84,7 @@ CompileCache::wait_pending() { std::lock_guard<std::mutex> guard(_lock); for (auto entry = _cached.begin(); entry != _cached.end(); ++entry) { - if (entry->second.compiled_function.get() == nullptr) { + if (entry->second.cf.load(std::memory_order_acquire) == nullptr) { ++(entry->second.num_refs); pending.push_back(std::make_unique<Token>(entry, Token::ctor_tag())); } @@ -129,7 +129,7 @@ CompileCache::count_pending() std::lock_guard<std::mutex> guard(_lock); size_t pending = 0; for (const auto &entry: _cached) { - if (entry.second.compiled_function.get() == nullptr) { + if (entry.second.cf.load(std::memory_order_acquire) == nullptr) { ++pending; } } @@ -141,7 +141,7 @@ CompileCache::CompileTask::run() { auto &entry = token->_entry->second; auto result = std::make_unique<CompiledFunction>(*function, pass_params); - std::lock_guard<std::mutex> guard(_lock); + std::lock_guard<std::mutex> guard(entry.result_lock); entry.compiled_function = std::move(result); entry.cf.store(entry.compiled_function.get(), std::memory_order_release); entry.cond.notify_all(); diff --git a/eval/src/vespa/eval/eval/llvm/compile_cache.h b/eval/src/vespa/eval/eval/llvm/compile_cache.h index 09b5b2060f5..e8f87e454d3 100644 --- a/eval/src/vespa/eval/eval/llvm/compile_cache.h +++ b/eval/src/vespa/eval/eval/llvm/compile_cache.h @@ -26,10 +26,11 @@ private: struct Value { size_t num_refs; std::atomic<const CompiledFunction *> cf; + std::mutex result_lock; std::condition_variable cond; CompiledFunction::UP compiled_function; struct ctor_tag {}; - Value(ctor_tag) : num_refs(1), cf(nullptr), cond(), compiled_function() {} + Value(ctor_tag) : num_refs(1), cf(nullptr), result_lock(), cond(), compiled_function() {} const CompiledFunction &wait_for_result(); const CompiledFunction &get() { const CompiledFunction *ptr = cf.load(std::memory_order_acquire); |