[LLVMdev] Problems with parallelizing lli

Adda Rathbone addarathbone at googlemail.com
Wed Mar 20 14:01:37 PDT 2013


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;
+}


More information about the llvm-dev mailing list