LLVM: lib/Support/Jobserver.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
13#include "llvm/Config/llvm-config.h"
17
18#include
19#include
20#include
21#include
22
23#define DEBUG_TYPE "jobserver"
24
25using namespace llvm;
26
27namespace {
28struct FdPair {
29 int Read = -1;
32};
33
34struct JobserverConfig {
37 PosixFifo,
38 PosixPipe,
39 Win32Semaphore,
40 };
42 std::string Path;
43 FdPair PipeFDs;
44};
45
46
47
48
50 if (Input.consume_front(Prefix)) {
52 return true;
53 }
54 return false;
55}
56
57
58
59
60static std::optional getFileDescriptorPair(StringRef Input) {
61 FdPair FDs;
62 if (Input.consumeInteger(10, FDs.Read))
63 return std::nullopt;
64 if (.consume_front(","))
65 return std::nullopt;
66 if (Input.consumeInteger(10, FDs.Write))
67 return std::nullopt;
68 if (.empty() || !FDs.isValid())
69 return std::nullopt;
70 return FDs;
71}
72
73
74
75
76
77
79 JobserverConfig Config;
80 if (MakeFlags.empty())
81 return Config;
82
83
86
87
88
89 if (!Args.empty() && !Args[0].starts_with("-") && Args[0].contains('n'))
90 return Config;
91
92
93
96 if (getPrefixedValue(Arg, "--jobserver-auth=", Value)) {
97
98 if (auto FDPair = getFileDescriptorPair(Value)) {
99 Config.TheMode = JobserverConfig::PosixPipe;
100 Config.PipeFDs = *FDPair;
101 } else {
103
104 if (getPrefixedValue(Value, "fifo:", FifoPath)) {
105 Config.TheMode = JobserverConfig::PosixFifo;
106 Config.Path = FifoPath.str();
107 } else {
108
109 Config.TheMode = JobserverConfig::Win32Semaphore;
110 Config.Path = Value.str();
111 }
112 }
113 } else if (getPrefixedValue(Arg, "--jobserver-fds=", Value)) {
114
115 if (auto FDPair = getFileDescriptorPair(Value)) {
116 Config.TheMode = JobserverConfig::PosixPipe;
117 Config.PipeFDs = *FDPair;
118 } else {
120 "Invalid file descriptor pair in MAKEFLAGS");
121 }
122 }
123 }
124
125
126#ifdef _WIN32
127 if (Config.TheMode == JobserverConfig::PosixFifo ||
128 Config.TheMode == JobserverConfig::PosixPipe)
131 "FIFO/Pipe-based jobserver is not supported on Windows");
132#else
133 if (Config.TheMode == JobserverConfig::Win32Semaphore)
136 "Semaphore-based jobserver is not supported on this platform");
137#endif
138 return Config;
139}
140
141std::once_flag GJobserverOnceFlag;
143
144}
145
146namespace llvm {
148 bool IsInitialized = false;
149 std::atomic HasImplicitSlot{true};
150 unsigned NumJobs = 0;
151
152public:
155
158 unsigned getNumJobs() const override { return NumJobs; }
159
160 bool isValid() const { return IsInitialized; }
161
162private:
163#if defined(LLVM_ON_UNIX)
164 int ReadFD = -1;
165 int WriteFD = -1;
166 std::string FifoPath;
167#elif defined(_WIN32)
168 void *Semaphore = nullptr;
169#endif
170};
171}
172
173
174#if defined(LLVM_ON_UNIX)
176#elif defined(_WIN32)
178#else
179
184#endif
185
186namespace llvm {
188
190 assert(isExplicit() && "Cannot get value of implicit or invalid slot");
191 return static_cast<uint8_t>(Value);
192}
193
194
195
196
197
198
199
201 std::call_once(GJobserverOnceFlag, []() {
204 << "JobserverClient::getInstance() called for the first time.\n");
205 const char *MakeFlagsEnv = getenv("MAKEFLAGS");
206 if (!MakeFlagsEnv) {
207 errs() << "Warning: failed to create jobserver client due to MAKEFLAGS "
208 "environment variable not found\n";
209 return;
210 }
211
212 LLVM_DEBUG(dbgs() << "Found MAKEFLAGS = \"" << MakeFlagsEnv << "\"\n");
213
214 auto ConfigOrErr = parseNativeMakeFlags(MakeFlagsEnv);
215 if (Error Err = ConfigOrErr.takeError()) {
216 errs() << "Warning: failed to create jobserver client due to invalid "
217 "MAKEFLAGS environment variable: "
218 << toString(std::move(Err)) << "\n";
219 return;
220 }
221
222 JobserverConfig Config = *ConfigOrErr;
223 if (Config.TheMode == JobserverConfig::None) {
224 errs() << "Warning: failed to create jobserver client due to jobserver "
225 "mode missing in MAKEFLAGS environment variable\n";
226 return;
227 }
228
229 if (Config.TheMode == JobserverConfig::PosixPipe) {
230#if defined(LLVM_ON_UNIX)
231 if (!areFdsValid(Config.PipeFDs.Read, Config.PipeFDs.Write)) {
232 errs() << "Warning: failed to create jobserver client due to invalid "
233 "Pipe FDs in MAKEFLAGS environment variable\n";
234 return;
235 }
236#endif
237 }
238
239 auto Client = std::make_unique(Config);
240 if (Client->isValid()) {
241 LLVM_DEBUG(dbgs() << "Jobserver client created successfully!\n");
242 GJobserver = Client.release();
243 } else
244 errs() << "Warning: jobserver client initialization failed.\n";
245 });
246 return GJobserver;
247}
248
249
250
251
252
254 delete GJobserver;
255 GJobserver = nullptr;
256
257 new (&GJobserverOnceFlag) std::once_flag();
258}
259}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
The Input class is used to parse a yaml document into in-memory structs and vectors.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
A JobSlot represents a single job slot that can be acquired from or released to a jobserver pool.
uint8_t getExplicitValue() const
Definition Jobserver.cpp:189
JobserverClientImpl(const JobserverConfig &Config)
~JobserverClientImpl() override
void release(JobSlot Slot) override
Releases a job slot back to the pool.
JobSlot tryAcquire() override
Tries to acquire a job slot from the pool.
bool isValid() const
Definition Jobserver.cpp:160
unsigned getNumJobs() const override
Returns the number of job slots available, as determined on first use.
Definition Jobserver.cpp:158
The public interface for a jobserver client.
static LLVM_ABI_FOR_TEST JobserverClient * getInstance()
Returns the singleton instance of the JobserverClient.
Definition Jobserver.cpp:200
static LLVM_ABI_FOR_TEST void resetForTesting()
Resets the singleton instance. For testing purposes only.
Definition Jobserver.cpp:253
virtual ~JobserverClient()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
LLVM Value Representation.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
LLVM_ABI void SplitString(StringRef Source, SmallVectorImpl< StringRef > &OutFragments, StringRef Delimiters=" \t\n\v\f\r")
SplitString - Split up the specified string according to the specified delimiters,...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)