/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 | } |