diff options
author | Sam McCall <sammccall@google.com> | 2019-10-23 12:36:36 +0200 |
---|---|---|
committer | Sam McCall <sammccall@google.com> | 2019-10-23 12:48:38 +0200 |
commit | 40668abca4d307e02b33345cfdb7271549ff48d0 (patch) | |
tree | 8a5fcbf77abeb5a2d362182cef542215e742c0d4 /llvm/lib/Support/Threading.cpp | |
parent | 4b63ca1379a8a6399c3d29560623ee832c818919 (diff) | |
download | bcm5719-llvm-40668abca4d307e02b33345cfdb7271549ff48d0.tar.gz bcm5719-llvm-40668abca4d307e02b33345cfdb7271549ff48d0.zip |
[Support] Add a way to run a function on a detached thread
This roughly mimics `std::thread(...).detach()` except it allows to
customize the stack size. Required for https://reviews.llvm.org/D50993.
I've decided against reusing the existing `llvm_execute_on_thread` because
it's not obvious what to do with the ownership of the passed
function/arguments:
1. If we pass possibly owning functions data to `llvm_execute_on_thread`,
we'll lose the ability to pass small non-owning non-allocating functions
for the joining case (as it's used now). Is it important enough?
2. If we use the non-owning interface in the new use case, we'll force
clients to transfer ownership to the spawned thread manually, but
similar code would still have to exist inside
`llvm_execute_on_thread(_async)` anyway (as we can't just pass the same
non-owning pointer to pthreads and Windows implementations, and would be
forced to wrap it in some structure, and deal with its ownership.
Patch by Dmitry Kozhevnikov!
Differential Revision: https://reviews.llvm.org/D51103
Diffstat (limited to 'llvm/lib/Support/Threading.cpp')
-rw-r--r-- | llvm/lib/Support/Threading.cpp | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/llvm/lib/Support/Threading.cpp b/llvm/lib/Support/Threading.cpp index e5899a60f4d..48750cef5ec 100644 --- a/llvm/lib/Support/Threading.cpp +++ b/llvm/lib/Support/Threading.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Threading.h" +#include "llvm/ADT/Optional.h" #include "llvm/Config/config.h" #include "llvm/Support/Host.h" @@ -39,8 +40,8 @@ bool llvm::llvm_is_multithreaded() { (!defined(_WIN32) && !defined(HAVE_PTHREAD_H)) // Support for non-Win32, non-pthread implementation. void llvm::llvm_execute_on_thread(void (*Fn)(void *), void *UserData, - unsigned RequestedStackSize) { - (void)RequestedStackSize; + llvm::Optional<unsigned> StackSizeInBytes) { + (void)StackSizeInBytes; Fn(UserData); } @@ -56,6 +57,25 @@ void llvm::set_thread_name(const Twine &Name) {} void llvm::get_thread_name(SmallVectorImpl<char> &Name) { Name.clear(); } +#if LLVM_ENABLE_THREADS == 0 +void llvm::llvm_execute_on_thread_async( + llvm::unique_function<void()> Func, + llvm::Optional<unsigned> StackSizeInBytes) { + (void)Func; + (void)StackSizeInBytes; + report_fatal_error("Spawning a detached thread doesn't make sense with no " + "threading support"); +} +#else +// Support for non-Win32, non-pthread implementation. +void llvm::llvm_execute_on_thread_async( + llvm::unique_function<void()> Func, + llvm::Optional<unsigned> StackSizeInBytes) { + (void)StackSizeInBytes; + std::thread(std::move(Func)).detach(); +} +#endif + #else #include <thread> @@ -84,6 +104,17 @@ unsigned llvm::hardware_concurrency() { return 1; } +namespace { +struct SyncThreadInfo { + void (*UserFn)(void *); + void *UserData; +}; + +using AsyncThreadInfo = llvm::unique_function<void()>; + +enum class JoiningPolicy { Join, Detach }; +} // namespace + // Include the platform-specific parts of this class. #ifdef LLVM_ON_UNIX #include "Unix/Threading.inc" @@ -92,4 +123,20 @@ unsigned llvm::hardware_concurrency() { #include "Windows/Threading.inc" #endif +void llvm::llvm_execute_on_thread(void (*Fn)(void *), void *UserData, + llvm::Optional<unsigned> StackSizeInBytes) { + + SyncThreadInfo Info = {Fn, UserData}; + llvm_execute_on_thread_impl(threadFuncSync, &Info, StackSizeInBytes, + JoiningPolicy::Join); +} + +void llvm::llvm_execute_on_thread_async( + llvm::unique_function<void()> Func, + llvm::Optional<unsigned> StackSizeInBytes) { + llvm_execute_on_thread_impl(&threadFuncAsync, + new AsyncThreadInfo(std::move(Func)), + StackSizeInBytes, JoiningPolicy::Detach); +} + #endif |