Skip to content

Commit 56d9c20

Browse files
committed
Fix typos
1 parent 8dffbd4 commit 56d9c20

File tree

6 files changed

+26
-24
lines changed

6 files changed

+26
-24
lines changed

Sources/XCRemoteCache/Commands/SwiftFrontend/SwiftFrontendContext.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@ struct SwiftFrontendContext {
2626

2727
extension SwiftFrontendContext {
2828
init(_ swiftcContext: SwiftcContext, env: [String: String]) throws {
29-
/// The LLBUILD_BUILD_ID ENV that describes the swiftc (parent) invocation
29+
/// The LLBUILD_BUILD_ID ENV that describes the entire (incl. parent's swiftc) bui;d
3030
let llbuildId: String = try env.readEnv(key: "LLBUILD_BUILD_ID")
3131
invocationLockFile = Self.self.buildLlbuildIdSharedLockUrl(
3232
llbuildId: llbuildId,
3333
tmpDir: swiftcContext.tempDir
3434
)
3535
}
3636

37-
/// Generate the filename to be used to sycnhronize mutliple swift-frontend invocations
37+
/// Generate the filename to be used to synchronize multiple swift-frontend invocations
3838
/// The same file is used in prebuild, xcswift-frontend and postbuild (to clean it up)
3939
static func buildLlbuildIdSharedLockUrl(llbuildId: String, tmpDir: URL) -> URL {
4040
return tmpDir.appendingPathComponent(llbuildId).appendingPathExtension("lock")

Sources/XCRemoteCache/Commands/SwiftFrontend/SwiftFrontendOrchestrator.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ import Foundation
2121

2222
/// Manages the `swift-frontend` logic
2323
protocol SwiftFrontendOrchestrator {
24-
/// Executes the criticial secion according to the required order
24+
/// Executes the critical section according to the required order
2525
/// - Parameter criticalSection: the block that should be synchronized
2626
func run(criticalSection: () -> Void ) throws
2727
}
2828

2929
/// The default orchestrator that manages the order or swift-frontend invocations
30-
/// For emit-module (the "first" process) action, it locks a shared file between all swift-frontend invcations,
31-
/// verifies that the mocking can be done and continues the mocking/fallbacking along the lock release
32-
/// For the compilation action, tries to ackquire a lock and waits until the "emit-module" makes a decision
30+
/// For emit-module (the "first" process) action, it locks a shared file between all swift-frontend invocations,
31+
/// verifies that the mocking can be done and continues the mocking/fall-backing along the lock release
32+
/// For the compilation action, tries to acquire a lock and waits until the "emit-module" makes a decision
3333
/// if the compilation should be skipped and a "mocking" should used instead
3434
class CommonSwiftFrontendOrchestrator {
3535
/// Content saved to the shared file
@@ -78,7 +78,7 @@ class CommonSwiftFrontendOrchestrator {
7878
}
7979

8080

81-
/// Foor emit-module, wrap the critical section with the shared lock so other processes (compilation)
81+
/// For emit-module, wrap the critical section with the shared lock so other processes (compilation)
8282
/// have to wait until emit-module finishes
8383
/// Once the emit-module is done, the "magical" string is saved to the file and the lock is released
8484
///
@@ -95,8 +95,8 @@ class CommonSwiftFrontendOrchestrator {
9595
try lockAccessor.exclusiveAccess { handle in
9696
debugLog("starting the emit-module step: locked")
9797
// writing to the file content proactively - incase the critical section never returns
98-
// (in case of a fallback to the local compilation), all awaiting swift-frontent processes
99-
// will be immediatelly unblocked
98+
// (in case of a fallback to the local compilation), all awaiting swift-frontend processes
99+
// will be immediately unblocked
100100
handle.write(Self.self.emitModuleContent)
101101
try criticalSection()
102102
debugLog("lock file emit-module criticial end")
@@ -126,7 +126,7 @@ class CommonSwiftFrontendOrchestrator {
126126
if !executed && Date().timeIntervalSince(startingDate) > self.maxLockTimeout {
127127
errorLog("""
128128
Executing command \(action) without lock synchronization. That may be cause by the\
129-
crashed or extremly long emit-module. Contact XCRemoteCache authors about this error.
129+
crashed or extremely long emit-module. Contact XCRemoteCache authors about this error.
130130
""")
131131
try criticalSection()
132132
executed = true

Sources/XCRemoteCache/Dependencies/CacheModeController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class PhaseCacheModeController: CacheModeController {
124124
// this is just a non-critical cleanup step to not leave {{LLBUILD_BUILD_ID}}.lock
125125
// files in $TARGET_TEMP_DIR. It is expected that both prebuild and postbuild will
126126
// invoke it, to ensure:
127-
// - swift-frontent synchronization is done per-target build
127+
// - swift-frontend synchronization is done per-target build
128128
// - no .lock leftover files
129129
private func cleanupLlBuildLock() throws {
130130
if fileManager.fileExists(atPath: llbuildLockFile.path) {

Sources/xcswift-frontend/XCSwiftcFrontendMain.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ public class XCSwiftcFrontendMain {
2929
// swiftlint:disable:next function_body_length cyclomatic_complexity
3030
public func main() {
3131
let env = ProcessInfo.processInfo.environment
32-
// Do not invoke raw swift-frontend because that would lead to the invifnite loop
32+
// Do not invoke raw swift-frontend because that would lead to the infinite loop
3333
// swift-frontent -> xcswift-frontent -> swift-frontent
3434
//
3535
// Note: Returning the `swiftc` executaion here because it is possible to pass all arguments
36-
// from swift-frontent to `swiftc` and swiftc will be able to redirect to swift-frontend
36+
// from swift-frontend to `swiftc` and swiftc will be able to redirect to swift-frontend
3737
// (because the first argument is `-frontend`). If that is not a case (might change in
38-
// future swift compiler versions), invoke swift-frontent from the Xcode, but that introduces
38+
// future swift compiler versions), invoke swift-frontend from the Xcode, but that introduces
3939
// a limitation that disallows custom toolchains in Xcode:
4040
// $DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/bin/{ ProcessInfo().processName}
4141
let command = "swiftc"
@@ -110,7 +110,7 @@ public class XCSwiftcFrontendMain {
110110
docPath: docPath,
111111
supplementaryOutputFileMap: supplementaryOutputFileMap
112112
)
113-
// swift-frontened is first invoked with some "probing" args like
113+
// swift-frontend is first invoked with some "probing" args like
114114
// -print-target-info
115115
guard emitModule != compile else {
116116
runFallback(envs: env)

Tests/XCRemoteCacheTests/Commands/SwiftFrontendOrchestratorTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ final class SwiftFrontendOrchestratorTests: FileXCTestCase {
3434
try fileManager.write(toPath: emptyFile.path, contents: .init())
3535
}
3636

37-
func testRunsCriticalSectionImmediatellyForProducer() throws {
37+
func testRunsCriticalSectionImmediatelyForProducer() throws {
3838
let orchestrator = CommonSwiftFrontendOrchestrator(
3939
mode: .producer,
4040
action: .compile,
@@ -49,7 +49,7 @@ final class SwiftFrontendOrchestratorTests: FileXCTestCase {
4949
XCTAssertTrue(invoked)
5050
}
5151

52-
func testRunsCriticalSectionImmediatellyForDisabledConsumer() throws {
52+
func testRunsCriticalSectionImmediatelyForDisabledConsumer() throws {
5353
let orchestrator = CommonSwiftFrontendOrchestrator(
5454
mode: .consumer(commit: .unavailable),
5555
action: .compile,

docs/design/SwiftDriverIntegration.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
## Swift Driver Integration
22

3-
### Pre Swift Driver Integraiton
3+
### Pre Swift Driver Integration
44

5-
Historically (prior to Xcode 14), Swift compilation step was invoked by Xcode as a single external process. Xcode was calling `swiftc` and passed all required parameters (like all input files, output destinations, header paths etc.), and read its standard output to recognize the status of a compilation. Esentially, there were two build systems: "the big one" from Xcode and "small one" by Swift.
5+
Historically (prior to Xcode 14), Swift compilation step was invoked by Xcode as a single external process. Xcode was calling `swiftc` and passing all required parameters (like all input files, output destinations, header paths etc.), and reading its standard output to recognize the status/state of a compilation. Essentially, there were two build systems: "the big one" from Xcode and "small one" by Swift.
66

7-
That design was easy to mock using XCRemoteCache, where the `xcswiftc` wrapper was first inspecting if the cached artifact can be reused (e.g. no new input `.swift` files were added to the list of compilation files) and based on that either continued with the local compilation or mocking the compilation and existing early (cache hit).
7+
That design was easy to mock in the XCRemoteCache, where the `xcswiftc` wrapper was first inspecting if the cached artifact can be reused (e.g. no new input `.swift` files were added to the list of compilation files) and based on that either continuing with the local compilation (cache miss) or mocking the compilation and existing early (cache hit).
88

99
![Pre Swift Driver Integration](./../img/pre-driver.png)
1010

1111

1212
### Swift Driver Integration Design
1313

14-
With the upgraded design, Xcode splits the work into `n` subprocesses (when `n` is ~CPU), each responsible to compile a subset of files/actions. To mitigate that, XCRemoteCache sets a single place to identify if the cached artifact is applicable - in a `swift-frontend` process responsible for module emitting. It has been found that this process is scheduled very early int the workflow timeline (with some aproximation, we could say it is scheduled as a first step) so it seems as best candidate for the "pre-work".
14+
With the upgraded design (aka Swift Driver Integration), Xcode splits the work into `n` subprocesses (when `n` is ~CPU), each responsible to compile a subset of files/actions. To align with that, XCRemoteCache meeds to specify a single place to identify if the cached artifact is applicable. `swift-frontend` has been picked for that - process responsible for module emitting. By reviewing Xcode's behavior, it has been found that this process is scheduled very early in the workflow timeline (with some approximation, we could say it is scheduled as a first step) so it seems as best candidate for the "pre-work".
1515

16-
As the same executable is invoked multiple times for the same target (emit module, and multiple batches of compilation), XCRemoteCaches uses a file lock-based synchronization. Each `xcswift-frontend` (the wrapper for `swift-frontend`) tries to acquire a target-unique lock file (the file has a name equal to the `LLBUILD_BUILD_ID` ENV, which is unique for each build, and the file is placed in the `Intermediate` directory) and reads its content to find if the "pre-work" from the emit-module has been already done or not. As a lock file is unique per target and a build (it is actually unique per target compilation, as placed in `TARGET_TEMP_DIR`), initially the file is empty. If any of a non emit module invocation sees a file is empty (note that before reading, it acquires a shared lock), the lock is immediatelly released to quickly let the actual emit-module wrapper do the "pre-work". Emit module step holds a shared lock for the time of the entire process lifetime, so only once the "pre-work" is finished, all other `xcswift-frontend` processes can continue their job (wither noop or fallbacking to the `swift-frontent` in case a cache miss). Non emit-module steps (often, but not exclusive, compilation steps) acquire a lock only for a very short perdio - to read the content of that file so they could run in parallel.s
16+
As the same executable `swift-frontend` is invoked multiple times for the same target (e.g. to emit module, multiple batches of compilation etc.), XCRemoteCaches uses a file lock-based synchronization. Each `xcswift-frontend` (the wrapper for `swift-frontend`) tries to acquire a unique lock file. The lock has a name `$LLBUILD_BUILD_ID.lock`, which is unique for each build, placed in the `Intermediate` directory. `xcswift-frontend` process reads its content to find if the "pre-work" from the emit-module has already been done - if not, it releases a lock a gives a way to other processes (presumably the "emit-module") to do the required work. As a lock file is unique per target and a build (it is actually unique per target compilation, placed in `TARGET_TEMP_DIR`), initially the file is empty.
17+
18+
Note the emit module step holds a shared lock for the time of the entire process lifetime, so only once the "pre-work" is finished, all other `xcswift-frontend` processes can continue their job (with either noop or fallbacking to the `swift-frontend` in case a cache miss). Non emit-module steps (compilation steps) acquire a lock only for a very short period - to read the content of that file, thus multiple batches of compilation can run in parallel.
1719

1820
![Pre Swift Driver Integration](./../img/driver.png)
1921

@@ -31,5 +33,5 @@ As the same executable is invoked multiple times for the same target (emit modul
3133

3234
### Other considerations/open questions
3335

34-
* For mixed targets (ObjC&Swift), Xcode triggers `.m` compilation steps after the module emitting to ensure that the `-Swift.h` is available. That means, the synchronization algorithm will also postpone any `clang` invocations until the Swift "pre-work" is done - so mixed targets should behave the same way as in the non Swift Driver Integration flow
35-
* For the WMO mode (Whole Module Optimization), all compilation steps are combined into a single `swift-frontend` process. As the emit module step is still invoked first, the WMO flow build builds down to a special case of the non-WMO. Therefore, the same algoritm should work for WMO builds too.
36+
* For mixed targets (ObjC&Swift), Xcode triggers `.m` compilation steps **after** the module emitting to ensure that the `-Swift.h` is available for clang compilation. That means, the synchronization algorithm will postpone any `clang` invocations until the Swift "pre-work" is done. Therefore, mixed targets should behave the same way as in the non Swift Driver Integration flow
37+
* For the WMO (Whole Module Optimization) mode, all compilation steps are combined into a single `swift-frontend` process. As the emit-module step is still invoked first, the WMO flow build can be considered as a special case of the algorithm described above (where there is only one compilation invocation). Therefore, the presented algorithm will work for the WMO mode out of the box.

0 commit comments

Comments
 (0)