/home/arjun/llvm-project/llvm/lib/Support/Threading.cpp
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | //===-- llvm/Support/Threading.cpp- Control multithreading mode --*- C++ -*-==// | 
| 2 |  | // | 
| 3 |  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
| 4 |  | // See https://llvm.org/LICENSE.txt for license information. | 
| 5 |  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
| 6 |  | // | 
| 7 |  | //===----------------------------------------------------------------------===// | 
| 8 |  | // | 
| 9 |  | // This file defines helper functions for running LLVM in a multi-threaded | 
| 10 |  | // environment. | 
| 11 |  | // | 
| 12 |  | //===----------------------------------------------------------------------===// | 
| 13 |  |  | 
| 14 |  | #include "llvm/Support/Threading.h" | 
| 15 |  | #include "llvm/ADT/Optional.h" | 
| 16 |  | #include "llvm/Config/config.h" | 
| 17 |  | #include "llvm/Support/Host.h" | 
| 18 |  |  | 
| 19 |  | #include <cassert> | 
| 20 |  | #include <errno.h> | 
| 21 |  | #include <stdlib.h> | 
| 22 |  | #include <string.h> | 
| 23 |  |  | 
| 24 |  | using namespace llvm; | 
| 25 |  |  | 
| 26 |  | //===----------------------------------------------------------------------===// | 
| 27 |  | //=== WARNING: Implementation here must contain only TRULY operating system | 
| 28 |  | //===          independent code. | 
| 29 |  | //===----------------------------------------------------------------------===// | 
| 30 |  |  | 
| 31 | 12 | bool llvm::llvm_is_multithreaded() { | 
| 32 | 12 | #if LLVM_ENABLE_THREADS != 0 | 
| 33 | 12 |   return true; | 
| 34 |  | #else | 
| 35 |  |   return false; | 
| 36 |  | #endif | 
| 37 |  | } | 
| 38 |  |  | 
| 39 |  | #if LLVM_ENABLE_THREADS == 0 ||                                                \ | 
| 40 |  |     (!defined(_WIN32) && !defined(HAVE_PTHREAD_H)) | 
| 41 |  | // Support for non-Win32, non-pthread implementation. | 
| 42 |  | void llvm::llvm_execute_on_thread(void (*Fn)(void *), void *UserData, | 
| 43 |  |                                   llvm::Optional<unsigned> StackSizeInBytes) { | 
| 44 |  |   (void)StackSizeInBytes; | 
| 45 |  |   Fn(UserData); | 
| 46 |  | } | 
| 47 |  |  | 
| 48 |  | uint64_t llvm::get_threadid() { return 0; } | 
| 49 |  |  | 
| 50 |  | uint32_t llvm::get_max_thread_name_length() { return 0; } | 
| 51 |  |  | 
| 52 |  | void llvm::set_thread_name(const Twine &Name) {} | 
| 53 |  |  | 
| 54 |  | void llvm::get_thread_name(SmallVectorImpl<char> &Name) { Name.clear(); } | 
| 55 |  |  | 
| 56 |  | llvm::BitVector llvm::get_thread_affinity_mask() { return {}; } | 
| 57 |  |  | 
| 58 |  | unsigned llvm::ThreadPoolStrategy::compute_thread_count() const { | 
| 59 |  |   // When threads are disabled, ensure clients will loop at least once. | 
| 60 |  |   return 1; | 
| 61 |  | } | 
| 62 |  |  | 
| 63 |  | #if LLVM_ENABLE_THREADS == 0 | 
| 64 |  | void llvm::llvm_execute_on_thread_async( | 
| 65 |  |     llvm::unique_function<void()> Func, | 
| 66 |  |     llvm::Optional<unsigned> StackSizeInBytes) { | 
| 67 |  |   (void)Func; | 
| 68 |  |   (void)StackSizeInBytes; | 
| 69 |  |   report_fatal_error("Spawning a detached thread doesn't make sense with no " | 
| 70 |  |                      "threading support"); | 
| 71 |  | } | 
| 72 |  | #else | 
| 73 |  | // Support for non-Win32, non-pthread implementation. | 
| 74 |  | void llvm::llvm_execute_on_thread_async( | 
| 75 |  |     llvm::unique_function<void()> Func, | 
| 76 |  |     llvm::Optional<unsigned> StackSizeInBytes) { | 
| 77 |  |   (void)StackSizeInBytes; | 
| 78 |  |   std::thread(std::move(Func)).detach(); | 
| 79 |  | } | 
| 80 |  | #endif | 
| 81 |  |  | 
| 82 |  | #else | 
| 83 |  |  | 
| 84 |  | int computeHostNumHardwareThreads(); | 
| 85 |  |  | 
| 86 | 0 | unsigned llvm::ThreadPoolStrategy::compute_thread_count() const { | 
| 87 | 0 |   int MaxThreadCount = UseHyperThreads ? computeHostNumHardwareThreads() | 
| 88 | 0 |                                        : sys::getHostNumPhysicalCores(); | 
| 89 | 0 |   if (MaxThreadCount <= 0) | 
| 90 | 0 |     MaxThreadCount = 1; | 
| 91 | 0 |   if (ThreadsRequested == 0) | 
| 92 | 0 |     return MaxThreadCount; | 
| 93 | 0 |   if (!Limit) | 
| 94 | 0 |     return ThreadsRequested; | 
| 95 | 0 |   return std::min((unsigned)MaxThreadCount, ThreadsRequested); | 
| 96 | 0 | } | 
| 97 |  |  | 
| 98 |  | namespace { | 
| 99 |  | struct SyncThreadInfo { | 
| 100 |  |   void (*UserFn)(void *); | 
| 101 |  |   void *UserData; | 
| 102 |  | }; | 
| 103 |  |  | 
| 104 |  | using AsyncThreadInfo = llvm::unique_function<void()>; | 
| 105 |  |  | 
| 106 |  | enum class JoiningPolicy { Join, Detach }; | 
| 107 |  | } // namespace | 
| 108 |  |  | 
| 109 |  | // Include the platform-specific parts of this class. | 
| 110 |  | #ifdef LLVM_ON_UNIX | 
| 111 |  | #include "Unix/Threading.inc" | 
| 112 |  | #endif | 
| 113 |  | #ifdef _WIN32 | 
| 114 |  | #include "Windows/Threading.inc" | 
| 115 |  | #endif | 
| 116 |  |  | 
| 117 |  | void llvm::llvm_execute_on_thread(void (*Fn)(void *), void *UserData, | 
| 118 | 0 |                                   llvm::Optional<unsigned> StackSizeInBytes) { | 
| 119 | 0 | 
 | 
| 120 | 0 |   SyncThreadInfo Info = {Fn, UserData}; | 
| 121 | 0 |   llvm_execute_on_thread_impl(threadFuncSync, &Info, StackSizeInBytes, | 
| 122 | 0 |                               JoiningPolicy::Join); | 
| 123 | 0 | } | 
| 124 |  |  | 
| 125 |  | void llvm::llvm_execute_on_thread_async( | 
| 126 |  |     llvm::unique_function<void()> Func, | 
| 127 | 0 |     llvm::Optional<unsigned> StackSizeInBytes) { | 
| 128 | 0 |   llvm_execute_on_thread_impl(&threadFuncAsync, | 
| 129 | 0 |                               new AsyncThreadInfo(std::move(Func)), | 
| 130 | 0 |                               StackSizeInBytes, JoiningPolicy::Detach); | 
| 131 | 0 | } | 
| 132 |  |  | 
| 133 |  | #endif | 
| 134 |  |  | 
| 135 |  | Optional<ThreadPoolStrategy> | 
| 136 | 0 | llvm::get_threadpool_strategy(StringRef Num, ThreadPoolStrategy Default) { | 
| 137 | 0 |   if (Num == "all") | 
| 138 | 0 |     return llvm::hardware_concurrency(); | 
| 139 | 0 |   if (Num.empty()) | 
| 140 | 0 |     return Default; | 
| 141 | 0 |   unsigned V; | 
| 142 | 0 |   if (Num.getAsInteger(10, V)) | 
| 143 | 0 |     return None; // malformed 'Num' value | 
| 144 | 0 |   if (V == 0) | 
| 145 | 0 |     return Default; | 
| 146 | 0 |  | 
| 147 | 0 |   // Do not take the Default into account. This effectively disables | 
| 148 | 0 |   // heavyweight_hardware_concurrency() if the user asks for any number of | 
| 149 | 0 |   // threads on the cmd-line. | 
| 150 | 0 |   ThreadPoolStrategy S = llvm::hardware_concurrency(); | 
| 151 | 0 |   S.ThreadsRequested = V; | 
| 152 | 0 |   return S; | 
| 153 | 0 | } |