summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Fröhlich <[email protected]>2014-07-13 12:49:41 +0200
committerMathias Fröhlich <[email protected]>2014-09-30 20:51:02 +0200
commitd90ff351f3a3598834f77b9c0723532b3abd3cd5 (patch)
tree338b6fcba4f86b70fee872efca7d9947dee31eab
parent83c62597fc8eb38bf274fa1a3ca03c6adafb4bf9 (diff)
llvmpipe: Make a llvmpipe OpenGL context thread safe.
This fixes the remaining problem with the recently introduced global jit memory manager. This change again uses a memory manager that is local to gallivm_state. This implementation still frees the majority of the memory immediately after compilation. Only the generated code is deferred until this code is no longer used. This change and the previous one using private LLVMContext instances I can now safely run several independent OpenGL contexts driven by llvmpipe from different threads. v3: Rebase on llvm-3.6 compile fixes. Reviewed-by: Jose Fonseca <[email protected]> Signed-off-by: Mathias Froehlich <[email protected]>
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_init.c13
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_init.h1
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_misc.cpp41
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_misc.h3
4 files changed, 40 insertions, 18 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c
index 8a484978f1e..4e4aecb102c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c
@@ -219,6 +219,10 @@ gallivm_free_code(struct gallivm_state *gallivm)
assert(!gallivm->engine);
lp_free_generated_code(gallivm->code);
gallivm->code = NULL;
+#if HAVE_LLVM < 0x0306
+ LLVMDisposeMCJITMemoryManager(gallivm->memorymgr);
+ gallivm->memorymgr = NULL;
+#endif
}
@@ -240,6 +244,7 @@ init_gallivm_engine(struct gallivm_state *gallivm)
ret = lp_build_create_jit_compiler_for_module(&gallivm->engine,
&gallivm->code,
gallivm->module,
+ gallivm->memorymgr,
(unsigned) optlevel,
USE_MCJIT,
&error);
@@ -312,6 +317,14 @@ init_gallivm_state(struct gallivm_state *gallivm, const char *name,
if (!gallivm->builder)
goto fail;
+#if HAVE_LLVM < 0x0306
+ gallivm->memorymgr = lp_get_default_memory_manager();
+ if (!gallivm->memorymgr)
+ goto fail;
+#else
+ gallivm->memorymgr = 0;
+#endif
+
/* FIXME: MC-JIT only allows compiling one module at a time, and it must be
* complete when MC-JIT is created. So defer the MC-JIT engine creation for
* now.
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h
index 6e9f52554a3..9e50f88931d 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h
@@ -44,6 +44,7 @@ struct gallivm_state
LLVMPassManagerRef passmgr;
LLVMContextRef context;
LLVMBuilderRef builder;
+ LLVMMCJITMemoryManagerRef memorymgr;
struct lp_generated_code *code;
unsigned compiled;
};
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
index 06d29bcceeb..c173ab657b9 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -322,15 +322,15 @@ class DelegatingJITMemoryManager : public llvm::JITMemoryManager {
*/
class ShaderMemoryManager : public DelegatingJITMemoryManager {
- static llvm::JITMemoryManager *TheMM;
- static unsigned NumUsers;
+ llvm::JITMemoryManager *TheMM;
struct GeneratedCode {
typedef std::vector<void *> Vec;
Vec FunctionBody, ExceptionTable;
+ llvm::JITMemoryManager *TheMM;
- GeneratedCode() {
- ++NumUsers;
+ GeneratedCode(llvm::JITMemoryManager *MM) {
+ TheMM = MM;
}
~GeneratedCode() {
@@ -347,27 +347,20 @@ class ShaderMemoryManager : public DelegatingJITMemoryManager {
for ( i = ExceptionTable.begin(); i != ExceptionTable.end(); ++i )
TheMM->deallocateExceptionTable(*i);
#endif
- --NumUsers;
- if (NumUsers == 0) {
- delete TheMM;
- TheMM = 0;
- }
}
};
GeneratedCode *code;
llvm::JITMemoryManager *mgr() const {
- if (!TheMM) {
- TheMM = CreateDefaultMemManager();
- }
return TheMM;
}
public:
- ShaderMemoryManager() {
- code = new GeneratedCode;
+ ShaderMemoryManager(llvm::JITMemoryManager* MM) {
+ TheMM = MM;
+ code = new GeneratedCode(MM);
}
virtual ~ShaderMemoryManager() {
@@ -398,9 +391,6 @@ class ShaderMemoryManager : public DelegatingJITMemoryManager {
}
};
-llvm::JITMemoryManager *ShaderMemoryManager::TheMM = 0;
-unsigned ShaderMemoryManager::NumUsers = 0;
-
#endif
/**
@@ -418,6 +408,7 @@ LLVMBool
lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
lp_generated_code **OutCode,
LLVMModuleRef M,
+ LLVMMCJITMemoryManagerRef CMM,
unsigned OptLevel,
int useMCJIT,
char **OutError)
@@ -510,7 +501,8 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
builder.setMCPU(MCPU);
#endif
- ShaderMemoryManager *MM = new ShaderMemoryManager();
+ llvm::JITMemoryManager* JMM = reinterpret_cast<llvm::JITMemoryManager*>(CMM);
+ ShaderMemoryManager *MM = new ShaderMemoryManager(JMM);
*OutCode = MM->getGeneratedCode();
builder.setJITMemoryManager(MM);
@@ -549,3 +541,16 @@ lp_free_generated_code(struct lp_generated_code *code)
ShaderMemoryManager::freeGeneratedCode(code);
#endif
}
+
+extern "C"
+LLVMMCJITMemoryManagerRef
+lp_get_default_memory_manager()
+{
+#if HAVE_LLVM < 0x0306
+ llvm::JITMemoryManager *mm;
+ mm = llvm::JITMemoryManager::CreateDefaultMemManager();
+ return reinterpret_cast<LLVMMCJITMemoryManagerRef>(mm);
+#else
+ return 0;
+#endif
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.h b/src/gallium/auxiliary/gallivm/lp_bld_misc.h
index 64d2a04190f..40d3e797b4a 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.h
@@ -54,6 +54,7 @@ extern int
lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
struct lp_generated_code **OutCode,
LLVMModuleRef M,
+ LLVMMCJITMemoryManagerRef MM,
unsigned OptLevel,
int useMCJIT,
char **OutError);
@@ -61,6 +62,8 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
extern void
lp_free_generated_code(struct lp_generated_code *code);
+extern LLVMMCJITMemoryManagerRef
+lp_get_default_memory_manager();
#ifdef __cplusplus
}