LLVM 22.0.0git
Jobserver.inc
Go to the documentation of this file.
1//==- llvm/Support/Windows/Jobserver.inc - Windows Jobserver Impl -*- 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 implements the Windows-specific parts of the JobserverClient class.
10// On Windows, the jobserver is implemented using a named semaphore.
11//
12//===----------------------------------------------------------------------===//
13
15#include <atomic>
16#include <cassert>
17
18namespace llvm {
19/// The constructor for the Windows jobserver client. It attempts to open a
20/// handle to an existing named semaphore, the name of which is provided by
21/// GNU make in the --jobserver-auth argument. If the semaphore is opened
22/// successfully, the client is marked as initialized.
23JobserverClientImpl::JobserverClientImpl(const JobserverConfig &Config) {
24 Semaphore = (void *)::OpenSemaphoreA(SEMAPHORE_MODIFY_STATE | SYNCHRONIZE,
25 FALSE, Config.Path.c_str());
26 if (Semaphore != nullptr)
27 IsInitialized = true;
28}
29
30/// The destructor closes the handle to the semaphore, releasing the resource.
32 if (Semaphore != nullptr)
33 ::CloseHandle((HANDLE)Semaphore);
34}
35
36/// Tries to acquire a job slot. The first call always returns the implicit
37/// slot. Subsequent calls use a non-blocking wait on the semaphore
38/// (`WaitForSingleObject` with a timeout of 0). If the wait succeeds, the
39/// semaphore's count is decremented, and an explicit job slot is acquired.
40/// If the wait times out, it means no slots are available, and an invalid
41/// slot is returned.
43 if (!IsInitialized)
44 return JobSlot();
45
46 // First, grant the implicit slot.
47 if (HasImplicitSlot.exchange(false, std::memory_order_acquire)) {
49 }
50
51 // Try to acquire a slot from the semaphore without blocking.
52 if (::WaitForSingleObject((HANDLE)Semaphore, 0) == WAIT_OBJECT_0) {
53 // The explicit token value is arbitrary on Windows, as the semaphore
54 // count is the real resource.
56 }
57
58 return JobSlot(); // Invalid slot
59}
60
61/// Releases a job slot back to the pool. If the slot is implicit, it simply
62/// resets a flag. For an explicit slot, it increments the semaphore's count
63/// by one using `ReleaseSemaphore`, making the slot available to other
64/// processes.
66 if (!IsInitialized || !Slot.isValid())
67 return;
68
69 if (Slot.isImplicit()) {
70 [[maybe_unused]] bool was_already_released =
71 HasImplicitSlot.exchange(true, std::memory_order_release);
72 assert(!was_already_released && "Implicit slot released twice");
73 return;
74 }
75
76 // Release the slot by incrementing the semaphore count.
77 (void)::ReleaseSemaphore((HANDLE)Semaphore, 1, NULL);
78}
79} // namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
A JobSlot represents a single job slot that can be acquired from or released to a jobserver pool.
Definition Jobserver.h:77
static JobSlot createExplicit(uint8_t V)
Definition Jobserver.h:104
static JobSlot createImplicit()
Definition Jobserver.h:108
JobserverClientImpl(const JobserverConfig &Config)
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.
This is an optimization pass for GlobalISel generic memory operations.