25 if (::fstat(FD, &StatBuf) != 0)
27 return S_ISFIFO(StatBuf.st_mode);
31bool areFdsValid(
int ReadFD,
int WriteFD) {
32 if (ReadFD == -1 || WriteFD == -1)
35 return ::fcntl(ReadFD, F_GETFD) != -1 && ::fcntl(WriteFD, F_GETFD) != -1;
45JobserverClientImpl::JobserverClientImpl(
const JobserverConfig &Config) {
46 switch (Config.TheMode) {
47 case JobserverConfig::PosixPipe: {
49 int NewReadFD = ::dup(Config.PipeFDs.Read);
52 int NewWriteFD = ::dup(Config.PipeFDs.Write);
58 if (::fcntl(NewReadFD, F_SETFD, FD_CLOEXEC) == -1 ||
59 ::fcntl(NewWriteFD, F_SETFD, FD_CLOEXEC) == -1) {
65 int flags = ::fcntl(NewReadFD, F_GETFL, 0);
66 if (flags == -1 || ::fcntl(NewReadFD, F_SETFL, flags | O_NONBLOCK) == -1) {
75 case JobserverConfig::PosixFifo:
77 ReadFD = ::open(Config.Path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC);
78 if (ReadFD < 0 || !isFifo(ReadFD)) {
84 FifoPath = Config.Path;
95 SmallVector<JobSlot, 8> Slots;
97 auto S = tryAcquire();
100 Slots.push_back(std::move(S));
102 NumJobs = Slots.size();
103 assert(NumJobs >= 1 &&
"Invalid number of jobs");
104 for (
auto &S : Slots)
109JobserverClientImpl::~JobserverClientImpl() {
122JobSlot JobserverClientImpl::tryAcquire() {
127 if (HasImplicitSlot.exchange(
false, std::memory_order_acquire)) {
129 return JobSlot::createImplicit();
134 LLVM_DEBUG(
dbgs() <<
"Attempting to read token from FD " << ReadFD <<
".\n");
137 Ret = ::read(ReadFD, &Token, 1);
138 }
while (Ret < 0 && errno == EINTR);
141 LLVM_DEBUG(
dbgs() <<
"Acquired explicit token '" << Token <<
"'.\n");
142 return JobSlot::createExplicit(
static_cast<uint8_t>(Token));
145 LLVM_DEBUG(
dbgs() <<
"Failed to acquire job slot, read returned " << Ret
155void JobserverClientImpl::release(JobSlot Slot) {
160 if (
Slot.isImplicit()) {
162 [[maybe_unused]]
bool was_already_released =
163 HasImplicitSlot.exchange(
true, std::memory_order_release);
164 assert(!was_already_released &&
"Implicit slot released twice");
169 LLVM_DEBUG(
dbgs() <<
"Releasing explicit token '" << (
char)Token <<
"' to FD "
170 << WriteFD <<
".\n");
175 LLVM_DEBUG(
dbgs() <<
"WriteFD is invalid, opening FIFO: " << FifoPath
177 WriteFD = ::open(FifoPath.c_str(), O_WRONLY | O_CLOEXEC);
182 LLVM_DEBUG(
dbgs() <<
"Opened FIFO as new WriteFD: " << WriteFD <<
"\n");
188 Written =
::write(WriteFD, &Token, 1);
189 }
while (Written < 0 && errno == EINTR);
192 LLVM_DEBUG(
dbgs() <<
"Failed to write token to pipe, write returned "
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void write(bool isBE, void *P, T V)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.