X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FThreading.cpp;h=ca7f3f64aa37e37f3b7acbb815d0cba3b99bf4ff;hb=6c0e1e0fa658f4e7466c6787aedce992ece2db55;hp=a5876487e055890fcd0436f5137bb7c3c7ed1239;hpb=4c7ac18fc9e9af51ea6362871589c13263526d7a;p=oota-llvm.git diff --git a/lib/Support/Threading.cpp b/lib/Support/Threading.cpp index a5876487e05..ca7f3f64aa3 100644 --- a/lib/Support/Threading.cpp +++ b/lib/Support/Threading.cpp @@ -7,57 +7,106 @@ // //===----------------------------------------------------------------------===// // -// This file implements llvm_start_multithreaded() and friends. +// This file defines helper functions for running LLVM in a multi-threaded +// environment. // //===----------------------------------------------------------------------===// #include "llvm/Support/Threading.h" -#include "llvm/System/Atomic.h" -#include "llvm/System/Mutex.h" +#include "llvm/Config/config.h" +#include "llvm/Support/Atomic.h" +#include "llvm/Support/Mutex.h" #include using namespace llvm; -static bool multithreaded_mode = false; - -static sys::Mutex* global_lock = 0; - -bool llvm::llvm_start_multithreaded() { -#ifdef LLVM_MULTITHREADED - assert(!multithreaded_mode && "Already multithreaded!"); - multithreaded_mode = true; - global_lock = new sys::Mutex(true); - - // We fence here to ensure that all initialization is complete BEFORE we - // return from llvm_start_multithreaded(). - sys::MemoryFence(); +bool llvm::llvm_is_multithreaded() { +#if LLVM_ENABLE_THREADS != 0 return true; #else return false; #endif } -void llvm::llvm_stop_multithreaded() { -#ifdef LLVM_MULTITHREADED - assert(multithreaded_mode && "Not currently multithreaded!"); - - // We fence here to insure that all threaded operations are complete BEFORE we - // return from llvm_stop_multithreaded(). - sys::MemoryFence(); - - multithreaded_mode = false; - delete global_lock; -#endif +#if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H) +#include + +struct ThreadInfo { + void (*UserFn)(void *); + void *UserData; +}; +static void *ExecuteOnThread_Dispatch(void *Arg) { + ThreadInfo *TI = reinterpret_cast(Arg); + TI->UserFn(TI->UserData); + return nullptr; } -bool llvm::llvm_is_multithreaded() { - return multithreaded_mode; +void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData, + unsigned RequestedStackSize) { + ThreadInfo Info = { Fn, UserData }; + pthread_attr_t Attr; + pthread_t Thread; + + // Construct the attributes object. + if (::pthread_attr_init(&Attr) != 0) + return; + + // Set the requested stack size, if given. + if (RequestedStackSize != 0) { + if (::pthread_attr_setstacksize(&Attr, RequestedStackSize) != 0) + goto error; + } + + // Construct and execute the thread. + if (::pthread_create(&Thread, &Attr, ExecuteOnThread_Dispatch, &Info) != 0) + goto error; + + // Wait for the thread and clean up. + ::pthread_join(Thread, nullptr); + + error: + ::pthread_attr_destroy(&Attr); +} +#elif LLVM_ENABLE_THREADS!=0 && defined(LLVM_ON_WIN32) +#include "Windows/WindowsSupport.h" +#include + +struct ThreadInfo { + void (*func)(void*); + void *param; +}; + +static unsigned __stdcall ThreadCallback(void *param) { + struct ThreadInfo *info = reinterpret_cast(param); + info->func(info->param); + + return 0; } -void llvm::llvm_acquire_global_lock() { - if (multithreaded_mode) global_lock->acquire(); +void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData, + unsigned RequestedStackSize) { + struct ThreadInfo param = { Fn, UserData }; + + HANDLE hThread = (HANDLE)::_beginthreadex(NULL, + RequestedStackSize, ThreadCallback, + ¶m, 0, NULL); + + if (hThread) { + // We actually don't care whether the wait succeeds or fails, in + // the same way we don't care whether the pthread_join call succeeds + // or fails. There's not much we could do if this were to fail. But + // on success, this call will wait until the thread finishes executing + // before returning. + (void)::WaitForSingleObject(hThread, INFINITE); + ::CloseHandle(hThread); + } +} +#else +// Support for non-Win32, non-pthread implementation. +void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData, + unsigned RequestedStackSize) { + (void) RequestedStackSize; + Fn(UserData); } -void llvm::llvm_release_global_lock() { - if (multithreaded_mode) global_lock->release(); -} \ No newline at end of file +#endif