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 (Input.consume_front(","))

65 return std::nullopt;

66 if (Input.consumeInteger(10, FDs.Write))

67 return std::nullopt;

68 if (Input.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)