summaryrefslogtreecommitdiff
path: root/unittests
diff options
context:
space:
mode:
authorJuergen Ributzka <juergen@apple.com>2014-05-16 02:33:15 +0000
committerJuergen Ributzka <juergen@apple.com>2014-05-16 02:33:15 +0000
commit9bc1b73c9e30197d18b64fb9cf09dd45eaef256b (patch)
tree19301c341258da0cf14012dbb4c947c50cfc7415 /unittests
parent6d81fc75c495e8ed20f1508042bcd2edba1a8058 (diff)
downloadllvm-9bc1b73c9e30197d18b64fb9cf09dd45eaef256b.tar.gz
llvm-9bc1b73c9e30197d18b64fb9cf09dd45eaef256b.tar.bz2
llvm-9bc1b73c9e30197d18b64fb9cf09dd45eaef256b.tar.xz
Add C API for thread yielding callback.
Sometimes a LLVM compilation may take more time then a client would like to wait for. The problem is that it is not possible to safely suspend the LLVM thread from the outside. When the timing is bad it might be possible that the LLVM thread holds a global mutex and this would block any progress in any other thread. This commit adds a new yield callback function that can be registered with a context. LLVM will try to yield by calling this callback function, but there is no guaranteed frequency. LLVM will only do so if it can guarantee that suspending the thread won't block any forward progress in other LLVM contexts in the same process. Once the client receives the call back it can suspend the thread safely and resume it at another time. Related to <rdar://problem/16728690> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208945 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests')
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
index 3813d59dbd..20d3f139b4 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
@@ -28,6 +28,7 @@ using namespace llvm;
static bool didCallAllocateCodeSection;
static bool didAllocateCompactUnwindSection;
+static bool didCallYield;
static uint8_t *roundTripAllocateCodeSection(void *object, uintptr_t size,
unsigned alignment,
@@ -64,6 +65,10 @@ static void roundTripDestroy(void *object) {
delete static_cast<SectionMemoryManager*>(object);
}
+static void yield(LLVMContextRef, void *) {
+ didCallYield = true;
+}
+
namespace {
// memory manager to test reserve allocation space callback
@@ -142,6 +147,7 @@ protected:
virtual void SetUp() {
didCallAllocateCodeSection = false;
didAllocateCompactUnwindSection = false;
+ didCallYield = false;
Module = 0;
Function = 0;
Engine = 0;
@@ -429,3 +435,24 @@ TEST_F(MCJITCAPITest, reserve_allocation_space) {
EXPECT_TRUE(MM->UsedCodeSize > 0);
EXPECT_TRUE(MM->UsedDataSizeRW > 0);
}
+
+TEST_F(MCJITCAPITest, yield) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ buildSimpleFunction();
+ buildMCJITOptions();
+ buildMCJITEngine();
+ LLVMContextRef C = LLVMGetGlobalContext();
+ LLVMContextSetYieldCallback(C, yield, NULL);
+ buildAndRunPasses();
+
+ union {
+ void *raw;
+ int (*usable)();
+ } functionPointer;
+ functionPointer.raw = LLVMGetPointerToGlobal(Engine, Function);
+
+ EXPECT_EQ(42, functionPointer.usable());
+ EXPECT_TRUE(didCallYield);
+}
+