180814287SRaphael Isemann //===-- ThreadLauncher.cpp ------------------------------------------------===//
239de3110SZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
639de3110SZachary Turner //
739de3110SZachary Turner //===----------------------------------------------------------------------===//
839de3110SZachary Turner 
939de3110SZachary Turner // lldb Includes
10b9c1b51eSKate Stone #include "lldb/Host/ThreadLauncher.h"
1139de3110SZachary Turner #include "lldb/Host/HostNativeThread.h"
1239de3110SZachary Turner #include "lldb/Host/HostThread.h"
136f9e6901SZachary Turner #include "lldb/Utility/Log.h"
1439de3110SZachary Turner 
1539de3110SZachary Turner #if defined(_WIN32)
1639de3110SZachary Turner #include "lldb/Host/windows/windows.h"
1739de3110SZachary Turner #endif
1839de3110SZachary Turner 
1920ecec61SStella Stamenova #include "llvm/Support/WindowsError.h"
204936cbc9SJonas Devlieghere 
2139de3110SZachary Turner using namespace lldb;
2239de3110SZachary Turner using namespace lldb_private;
2339de3110SZachary Turner 
24*d0810779SPavel Labath llvm::Expected<HostThread>
LaunchThread(llvm::StringRef name,std::function<thread_result_t ()> impl,size_t min_stack_byte_size)25*d0810779SPavel Labath ThreadLauncher::LaunchThread(llvm::StringRef name,
26*d0810779SPavel Labath                              std::function<thread_result_t()> impl,
27*d0810779SPavel Labath                              size_t min_stack_byte_size) {
28*d0810779SPavel Labath   // Host::ThreadCreateTrampoline will take ownership if thread creation is
29*d0810779SPavel Labath   // successful.
30*d0810779SPavel Labath   auto info_up = std::make_unique<HostThreadCreateInfo>(name.str(), impl);
3139de3110SZachary Turner   lldb::thread_t thread;
3239de3110SZachary Turner #ifdef _WIN32
33b9c1b51eSKate Stone   thread = (lldb::thread_t)::_beginthreadex(
34b9c1b51eSKate Stone       0, (unsigned)min_stack_byte_size,
35*d0810779SPavel Labath       HostNativeThread::ThreadCreateTrampoline, info_up.get(), 0, NULL);
36ba06f15aSJonas Devlieghere   if (thread == LLDB_INVALID_HOST_THREAD)
37ba06f15aSJonas Devlieghere     return llvm::errorCodeToError(llvm::mapWindowsError(GetLastError()));
3839de3110SZachary Turner #else
39807b6b32SGreg Clayton 
403db7ebc8SJason Molenda // ASAN instrumentation adds a lot of bookkeeping overhead on stack frames.
413db7ebc8SJason Molenda #if __has_feature(address_sanitizer)
423db7ebc8SJason Molenda   const size_t eight_megabytes = 8 * 1024 * 1024;
43b9c1b51eSKate Stone   if (min_stack_byte_size < eight_megabytes) {
443db7ebc8SJason Molenda     min_stack_byte_size += eight_megabytes;
453db7ebc8SJason Molenda   }
463db7ebc8SJason Molenda #endif
473db7ebc8SJason Molenda 
48248a1305SKonrad Kleine   pthread_attr_t *thread_attr_ptr = nullptr;
49807b6b32SGreg Clayton   pthread_attr_t thread_attr;
50807b6b32SGreg Clayton   bool destroy_attr = false;
51b9c1b51eSKate Stone   if (min_stack_byte_size > 0) {
52b9c1b51eSKate Stone     if (::pthread_attr_init(&thread_attr) == 0) {
53807b6b32SGreg Clayton       destroy_attr = true;
54807b6b32SGreg Clayton       size_t default_min_stack_byte_size = 0;
55b9c1b51eSKate Stone       if (::pthread_attr_getstacksize(&thread_attr,
56b9c1b51eSKate Stone                                       &default_min_stack_byte_size) == 0) {
57b9c1b51eSKate Stone         if (default_min_stack_byte_size < min_stack_byte_size) {
58b9c1b51eSKate Stone           if (::pthread_attr_setstacksize(&thread_attr, min_stack_byte_size) ==
59b9c1b51eSKate Stone               0)
60807b6b32SGreg Clayton             thread_attr_ptr = &thread_attr;
61807b6b32SGreg Clayton         }
62807b6b32SGreg Clayton       }
63807b6b32SGreg Clayton     }
64807b6b32SGreg Clayton   }
65b9c1b51eSKate Stone   int err =
66b9c1b51eSKate Stone       ::pthread_create(&thread, thread_attr_ptr,
67*d0810779SPavel Labath                        HostNativeThread::ThreadCreateTrampoline, info_up.get());
68807b6b32SGreg Clayton 
69807b6b32SGreg Clayton   if (destroy_attr)
70807b6b32SGreg Clayton     ::pthread_attr_destroy(&thread_attr);
71807b6b32SGreg Clayton 
72f39c2e18SJonas Devlieghere   if (err)
73f39c2e18SJonas Devlieghere     return llvm::errorCodeToError(
74f39c2e18SJonas Devlieghere         std::error_code(err, std::generic_category()));
7539de3110SZachary Turner #endif
7639de3110SZachary Turner 
77*d0810779SPavel Labath   info_up.release();
7839de3110SZachary Turner   return HostThread(thread);
7939de3110SZachary Turner }
80