Hi,
I am trying to parallize the lli interpreter (code:
http://pastebin.com/6iuHNH3Q). I am using ubuntu 12.04 with llvm
version 3.1. Each thread uses a seperate LLVMContext, however the
interpreter continues to crash.
Error msg: ..../include/llvm/Support/Mutex.h:116:
bool llvm::sys::SmartMutex<true>::release(): Assertion `((recursive
&&
acquired) || (acquired == 1)) && "Lock not acquired before
release!"' failed."")))
What am I doing wrong?
Thank you.
Diff to original tools/lli/lli.cpp attached.
-------------- next part --------------
--- ../../tools/lli/lli.cpp 2012-04-18 10:34:12.000000000 +0200
+++ lli.cpp 2013-03-20 22:01:39.713989939 +0100
@@ -175,34 +175,23 @@
#endif
}
-//===----------------------------------------------------------------------===//
-// main Driver function
-//
-int main(int argc, char **argv, char * const *envp) {
- sys::PrintStackTraceOnErrorSignal();
- PrettyStackTraceProgram X(argc, argv);
-
- LLVMContext &Context = getGlobalContext();
- atexit(do_shutdown); // Call llvm_shutdown() on exit.
-
- // If we have a native target, initialize it to ensure it is linked in and
- // usable by the JIT.
- InitializeNativeTarget();
- InitializeNativeTargetAsmPrinter();
-
- cl::ParseCommandLineOptions(argc, argv,
- "llvm interpreter & dynamic
compiler\n");
-
- // If the user doesn't want core files, disable them.
- if (DisableCoreFiles)
- sys::Process::PreventCoreFiles();
-
+typedef struct {
+ int argc;
+ char **argv;
+ char *const *envp;
+} arg_t;
+
+void *run(void *arg) {
+ int argc = ((arg_t *) arg)->argc;
+ char **argv = ((arg_t *) arg)->argv;
+ char *const *envp = ((arg_t *) arg)->envp;
+ LLVMContext Context;
// Load the bitcode...
SMDiagnostic Err;
Module *Mod = ParseIRFile(InputFile, Err, Context);
if (!Mod) {
Err.print(argv[0], errs());
- return 1;
+ return (void *)1;
}
// If not jitting lazily, load the whole bitcode file eagerly too.
@@ -242,7 +231,7 @@
switch (OptLevel) {
default:
errs() << argv[0] << ": invalid optimization
level.\n";
- return 1;
+ return (void *)1;
case ' ': break;
case '0': OLvl = CodeGenOpt::None; break;
case '1': OLvl = CodeGenOpt::Less; break;
@@ -297,7 +286,7 @@
Function *EntryFn = Mod->getFunction(EntryFunc);
if (!EntryFn) {
errs() << '\'' << EntryFunc << "\'
function not found in module.\n";
- return -1;
+ return (void *)-1;
}
// If the program doesn't explicitly call exit, we will need the Exit
@@ -341,3 +330,48 @@
abort();
}
}
+
+
+//===----------------------------------------------------------------------===//
+// main Driver function
+//
+int main(int argc, char **argv, char * const *envp) {
+ sys::PrintStackTraceOnErrorSignal();
+ PrettyStackTraceProgram X(argc, argv);
+
+ atexit(do_shutdown); // Call llvm_shutdown() on exit.
+
+ // If we have a native target, initialize it to ensure it is linked in and
+ // usable by the JIT.
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+
+ cl::ParseCommandLineOptions(argc, argv,
+ "llvm interpreter & dynamic
compiler\n");
+
+ // If the user doesn't want core files, disable them.
+ if (DisableCoreFiles)
+ sys::Process::PreventCoreFiles();
+
+ arg_t *aa = new arg_t();
+ aa->argc = argc;
+ aa->argv = argv;
+ aa->envp = envp;
+ pthread_t t1, t2;
+ void *r1, *r2;
+
+
+ if(0 != pthread_create(&t1, NULL, &run, aa)) {
+ errs() << "Failed to create thread " <<
strerror(errno) << "\n";
+ return 66;
+ }
+
+ if(0 != pthread_create(&t2, NULL, &run, aa)) {
+ errs() << "Failed to create thread " <<
strerror(errno) << "\n";
+ return 67;
+ }
+
+ pthread_join(t1, &r1);
+ pthread_join(t2, &r2);
+ return (long) r1 | (long) r2;
+}