System: Add llvm_execute_on_thread, which does what it says.

- Primarily useful for running some code with a specified stack size, when
   pthreads are available.

llvm-svn: 118222
This commit is contained in:
Daniel Dunbar 2010-11-04 01:26:25 +00:00
parent 0fb841fd19
commit cdd4c5443e
2 changed files with 66 additions and 0 deletions

View File

@ -40,6 +40,20 @@ namespace llvm {
/// release_global_lock - Release the global lock. This is a no-op if called
/// before llvm_start_multithreaded().
void llvm_release_global_lock();
/// llvm_execute_on_thread - Execute the given \arg UserFn on a separate
/// thread, passing it the provided \arg UserData.
///
/// This function does not guarantee that the code will actually be executed
/// on a separate thread or honoring the requested stack size, but tries to do
/// so where system support is available.
///
/// \param UserFn - The callback to execute.
/// \param UserData - An argument to pass to the callback function.
/// \param RequestedStackSize - If non-zero, a requested size (in bytes) for
/// the thread stack.
void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,
unsigned RequestedStackSize = 0);
}
#endif

View File

@ -62,3 +62,55 @@ void llvm::llvm_acquire_global_lock() {
void llvm::llvm_release_global_lock() {
if (multithreaded_mode) global_lock->release();
}
#if defined(LLVM_MULTITHREADED) && defined(HAVE_PTHREAD_H)
#include <pthread.h>
struct ThreadInfo {
void (*UserFn)(void *);
void *UserData;
};
static void *ExecuteOnThread_Dispatch(void *Arg) {
ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg);
TI->UserFn(TI->UserData);
return 0;
}
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, 0);
error:
::pthread_attr_destroy(&Attr);
}
#else
// No non-pthread implementation, currently.
void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
unsigned RequestedStackSize) {
(void) RequestedStackSize;
Fn(UserData);
}
#endif