From ccc316fc6e7b224b27d048d2e68749f52e975681 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Thu, 23 Oct 2025 18:07:05 -0400 Subject: [PATCH] Add back manual locking ThreadSafeContext API It is difficult to remove the use of this in julia ATM. --- llvm/include/llvm-c/Orc.h | 6 +++++ .../ExecutionEngine/Orc/ThreadSafeModule.h | 23 +++++++++++++++++++ .../ExecutionEngine/Orc/OrcV2CBindings.cpp | 5 ++++ 3 files changed, 34 insertions(+) diff --git a/llvm/include/llvm-c/Orc.h b/llvm/include/llvm-c/Orc.h index ce8ee0de2d407..5897268e673cf 100644 --- a/llvm/include/llvm-c/Orc.h +++ b/llvm/include/llvm-c/Orc.h @@ -1099,6 +1099,12 @@ LLVM_C_ABI LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void); LLVM_C_ABI LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContextFromLLVMContext(LLVMContextRef Ctx); +/** + * Get a reference to the wrapped LLVMContext. + */ +LLVMContextRef +LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx); + /** * Dispose of a ThreadSafeContext. */ diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h b/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h index 03165895b85d0..c65a424253dd4 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h @@ -36,6 +36,16 @@ class ThreadSafeContext { }; public: + // RAII based lock for ThreadSafeContext. + class [[nodiscard]] Lock { + public: + Lock(std::shared_ptr S) : S(std::move(S)), L(this->S->Mutex) {} + + private: + std::shared_ptr S; + std::unique_lock L; + }; + /// Construct a null context. ThreadSafeContext() = default; @@ -62,6 +72,19 @@ class ThreadSafeContext { return F((const LLVMContext *)nullptr); } + /// Returns a pointer to the LLVMContext that was used to construct this + /// instance, or null if the instance was default constructed. + LLVMContext *getContext() { return S ? S->Ctx.get() : nullptr; } + + /// Returns a pointer to the LLVMContext that was used to construct this + /// instance, or null if the instance was default constructed. + const LLVMContext *getContext() const { return S ? S->Ctx.get() : nullptr; } + + Lock getLock() const { + assert(S && "Can not lock an empty ThreadSafeContext"); + return Lock(S); + } + private: std::shared_ptr S; }; diff --git a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp index fd805fbf01fb7..815750d3cf4b0 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp +++ b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp @@ -734,6 +734,11 @@ LLVMOrcCreateNewThreadSafeContextFromLLVMContext(LLVMContextRef Ctx) { return wrap(new ThreadSafeContext(std::unique_ptr(unwrap(Ctx)))); } +LLVMContextRef +LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx) { + return wrap(unwrap(TSCtx)->getContext()); +} + void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx) { delete unwrap(TSCtx); }