forked from OSchip/llvm-project
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:
parent
0fb841fd19
commit
cdd4c5443e
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue