Skip to content

Commit d788e44

Browse files
committed
Uses Native swift Atomics
Replaces the usage of CAtomics with the native Atomics from the swift library and bumps the development platform to macOS 15 Removes all references to CAtomics from the library Removes atomic wrappers infavor of using them directly Replacing the usage of Int32, and UInt32 with Int since the previous was only used because of c bridging Uses .sequentiallyConsistent for all loading and storing methods
1 parent 825c17e commit d788e44

28 files changed

+111
-273
lines changed

Contributor Documentation/Modules.md

-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ Swift types to represent the [Build Server Protocol (BSP) specification](https:/
1010

1111
Defines the queries SourceKit-LSP can ask of a build system, like getting compiler arguments for a file, finding a target’s dependencies or preparing a target.
1212

13-
### CAtomics
14-
15-
Implementation of atomics for Swift using C. Once we can raise our deployment target to use the `Atomic` type from the Swift standard library, this module should be removed.
16-
1713
### CSKTestSupport
1814

1915
For testing, overrides `__cxa_atexit` to prevent registration of static destructors due to work around https://github.com/swiftlang/swift/issues/55112.

Package.swift

+1-10
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,6 @@ var targets: [Target] = [
112112
swiftSettings: globalSwiftSettings
113113
),
114114

115-
// MARK: CAtomics
116-
117-
.target(
118-
name: "CAtomics",
119-
dependencies: []
120-
),
121-
122115
.target(
123116
name: "CCompletionScoring",
124117
dependencies: []
@@ -526,14 +519,12 @@ var targets: [Target] = [
526519

527520
.target(
528521
name: "SwiftExtensions",
529-
dependencies: ["CAtomics"],
530522
exclude: ["CMakeLists.txt"],
531523
swiftSettings: globalSwiftSettings
532524
),
533525

534526
.target(
535527
name: "SwiftExtensionsForPlugin",
536-
dependencies: ["CAtomics"],
537528
exclude: ["CMakeLists.txt"],
538529
swiftSettings: globalSwiftSettings
539530
),
@@ -694,7 +685,7 @@ if buildOnlyTests {
694685

695686
let package = Package(
696687
name: "SourceKitLSP",
697-
platforms: [.macOS(.v13)],
688+
platforms: [.macOS("15")],
698689
products: products,
699690
dependencies: dependencies,
700691
targets: targets,

Sources/BuildSystemIntegration/SwiftPMBuildSystem.swift

+5-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import SKLogging
2222
@preconcurrency package import SPMBuildCore
2323
import SourceControl
2424
import SwiftExtensions
25+
import Synchronization
2526
import TSCExtensions
2627
@preconcurrency import Workspace
2728

@@ -88,7 +89,7 @@ fileprivate extension TSCBasic.AbsolutePath {
8889
}
8990
}
9091

91-
fileprivate let preparationTaskID: AtomicUInt32 = AtomicUInt32(initialValue: 0)
92+
fileprivate let preparationTaskID: Atomic<Int> = Atomic(0)
9293

9394
/// Swift Package Manager build system and workspace support.
9495
///
@@ -613,7 +614,9 @@ package actor SwiftPMBuildSystem: BuiltInBuildSystem {
613614
}
614615
let start = ContinuousClock.now
615616

616-
let taskID: TaskId = TaskId(id: "preparation-\(preparationTaskID.fetchAndIncrement())")
617+
let taskID: TaskId = TaskId(
618+
id: "preparation-\(preparationTaskID.add(1, ordering: .sequentiallyConsistent).oldValue)"
619+
)
617620
logMessageToIndexLog(
618621
taskID,
619622
"""

Sources/CAtomics/CAtomics.c

Whitespace-only changes.

Sources/CAtomics/CMakeLists.txt

-2
This file was deleted.

Sources/CAtomics/include/CAtomics.h

-73
This file was deleted.

Sources/CAtomics/include/module.modulemap

-4
This file was deleted.

Sources/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-DRESILIENT_LIBRARIES>")
33
add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-swift-version 6>")
44
add_subdirectory(BuildServerProtocol)
55
add_subdirectory(BuildSystemIntegration)
6-
add_subdirectory(CAtomics)
76
add_subdirectory(CCompletionScoring)
87
add_subdirectory(CompletionScoring)
98
add_subdirectory(Csourcekitd)

Sources/CompletionScoringTestSupport/TestExtensions.swift

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import Foundation
1414
import SwiftExtensions
15+
import Synchronization
1516
import XCTest
1617

1718
#if compiler(>=6)
@@ -106,7 +107,7 @@ extension XCTestCase {
106107
UserDefaults.standard.string(forKey: "TestMeasurementLogPath")
107108
}()
108109

109-
static let printBeginingOfLog = AtomicBool(initialValue: true)
110+
static let printBeginingOfLog: Atomic<Bool> = Atomic(true)
110111

111112
private static func openPerformanceLog() throws -> FileHandle? {
112113
try measurementsLogFile.map { path in
@@ -119,9 +120,9 @@ extension XCTestCase {
119120
}
120121
let logFD = try FileHandle(forWritingAtPath: path).unwrap(orThrow: "Opening \(path) failed")
121122
try logFD.seekToEnd()
122-
if printBeginingOfLog.value {
123+
if printBeginingOfLog.load(ordering: .sequentiallyConsistent) {
123124
try logFD.print("========= \(Date().description(with: .current)) =========")
124-
printBeginingOfLog.value = false
125+
printBeginingOfLog.store(false, ordering: .sequentiallyConsistent)
125126
}
126127
return logFD
127128
}

Sources/Diagnose/DiagnoseCommand.swift

+8-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import Synchronization
14+
1315
#if compiler(>=6)
1416
package import ArgumentParser
1517
import Foundation
@@ -233,8 +235,8 @@ package struct DiagnoseCommand: AsyncParsableCommand {
233235
throw GenericError("Failed to create log.txt")
234236
}
235237
let fileHandle = try FileHandle(forWritingTo: outputFileUrl)
236-
let bytesCollected = AtomicInt32(initialValue: 0)
237-
let processExited = AtomicBool(initialValue: false)
238+
let bytesCollected: Atomic<Int> = Atomic(0)
239+
let processExited: Atomic<Bool> = Atomic(false)
238240
// 50 MB is an average log size collected by sourcekit-lsp diagnose.
239241
// It's a good proxy to show some progress indication for the majority of the time.
240242
let expectedLogSize = 50_000_000
@@ -250,16 +252,16 @@ package struct DiagnoseCommand: AsyncParsableCommand {
250252
outputRedirection: .stream(
251253
stdout: { @Sendable bytes in
252254
try? fileHandle.write(contentsOf: bytes)
253-
bytesCollected.value += Int32(bytes.count)
254-
var progress = Double(bytesCollected.value) / Double(expectedLogSize)
255+
let count = bytesCollected.add(bytes.count, ordering: .sequentiallyConsistent).newValue
256+
var progress = Double(count) / Double(expectedLogSize)
255257
if progress > 1 {
256258
// The log is larger than we expected. Halt at 100%
257259
progress = 1
258260
}
259261
Task(priority: .high) {
260262
// We have launched an async task to call `reportProgress`, which means that the process might have exited
261263
// before we execute this task. To avoid overriding a more recent progress, add a guard.
262-
if !processExited.value {
264+
if !processExited.load(ordering: .sequentiallyConsistent) {
263265
await reportProgress(.collectingLogMessages(progress: progress), message: "Collecting log messages")
264266
}
265267
}
@@ -269,7 +271,7 @@ package struct DiagnoseCommand: AsyncParsableCommand {
269271
)
270272
try process.launch()
271273
try await process.waitUntilExit()
272-
processExited.value = true
274+
processExited.store(true, ordering: .sequentiallyConsistent)
273275
#endif
274276
}
275277

Sources/InProcessClient/InProcessSourceKitLSPClient.swift

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public import Foundation
1515
public import LanguageServerProtocol
1616
import LanguageServerProtocolExtensions
1717
import SwiftExtensions
18+
import Synchronization
1819
import TSCExtensions
1920

2021
import struct TSCBasic.AbsolutePath
@@ -33,7 +34,7 @@ import ToolchainRegistry
3334
public final class InProcessSourceKitLSPClient: Sendable {
3435
private let server: SourceKitLSPServer
3536

36-
private let nextRequestID = AtomicUInt32(initialValue: 0)
37+
private let nextRequestID: Atomic<Int> = Atomic(0)
3738

3839
public convenience init(
3940
toolchainPath: URL?,
@@ -101,7 +102,11 @@ public final class InProcessSourceKitLSPClient: Sendable {
101102

102103
/// Send the request to `server` and return the request result via a completion handler.
103104
public func send<R: RequestType>(_ request: R, reply: @Sendable @escaping (LSPResult<R.Response>) -> Void) {
104-
server.handle(request, id: .number(Int(nextRequestID.fetchAndIncrement())), reply: reply)
105+
server.handle(
106+
request,
107+
id: .number(Int(nextRequestID.add(1, ordering: .sequentiallyConsistent).oldValue)),
108+
reply: reply
109+
)
105110
}
106111

107112
/// Send the notification to `server`.

Sources/LanguageServerProtocolExtensions/QueueBasedMessageHandler.swift

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import Foundation
1414
import LanguageServerProtocolJSONRPC
1515
import SKLogging
16+
import Synchronization
1617

1718
#if compiler(>=6)
1819
package import LanguageServerProtocol
@@ -41,7 +42,7 @@ package actor QueueBasedMessageHandlerHelper {
4142
private let cancellationMessageHandlingQueue = AsyncQueue<Serial>()
4243

4344
/// Notifications don't have an ID. This represents the next ID we can use to identify a notification.
44-
private let notificationIDForLogging = AtomicUInt32(initialValue: 1)
45+
private let notificationIDForLogging: Atomic<Int> = Atomic(1)
4546

4647
/// The requests that we are currently handling.
4748
///
@@ -103,7 +104,7 @@ package actor QueueBasedMessageHandlerHelper {
103104
// Only use the last two digits of the notification ID for the logging scope to avoid creating too many scopes.
104105
// See comment in `withLoggingScope`.
105106
// The last 2 digits should be sufficient to differentiate between multiple concurrently running notifications.
106-
let notificationID = notificationIDForLogging.fetchAndIncrement()
107+
let notificationID = notificationIDForLogging.add(1, ordering: .sequentiallyConsistent).oldValue
107108
withLoggingScope("notification-\(notificationID % 100)") {
108109
body()
109110
}

Sources/LanguageServerProtocolExtensions/RequestAndReply.swift

+6-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import Synchronization
14+
1315
#if compiler(>=6)
1416
package import LanguageServerProtocol
1517
import SwiftExtensions
@@ -24,21 +26,21 @@ package final class RequestAndReply<Params: RequestType>: Sendable {
2426
private let replyBlock: @Sendable (LSPResult<Params.Response>) -> Void
2527

2628
/// Whether a reply has been made. Every request must reply exactly once.
27-
private let replied: AtomicBool = AtomicBool(initialValue: false)
29+
private let replied: Atomic<Bool> = Atomic(false)
2830

2931
package init(_ request: Params, reply: @escaping @Sendable (LSPResult<Params.Response>) -> Void) {
3032
self.params = request
3133
self.replyBlock = reply
3234
}
3335

3436
deinit {
35-
precondition(replied.value, "request never received a reply")
37+
precondition(replied.load(ordering: .sequentiallyConsistent), "request never received a reply")
3638
}
3739

3840
/// Call the `replyBlock` with the result produced by the given closure.
3941
package func reply(_ body: @Sendable () async throws -> Params.Response) async {
40-
precondition(!replied.value, "replied to request more than once")
41-
replied.value = true
42+
precondition(!replied.load(ordering: .sequentiallyConsistent), "replied to request more than once")
43+
replied.store(true, ordering: .sequentiallyConsistent)
4244
do {
4345
replyBlock(.success(try await body()))
4446
} catch {

Sources/SKLogging/NonDarwinLogging.swift

+5-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import Synchronization
14+
1315
#if compiler(>=6)
1416
package import SwiftExtensions
1517
#else
@@ -407,14 +409,14 @@ package struct NonDarwinLogger: Sendable {
407409
// MARK: - Signposter
408410

409411
package struct NonDarwinSignpostID: Sendable {
410-
fileprivate let id: UInt32
412+
fileprivate let id: Int
411413
}
412414

413415
package struct NonDarwinSignpostIntervalState: Sendable {
414416
fileprivate let id: NonDarwinSignpostID
415417
}
416418

417-
private let nextSignpostID = AtomicUInt32(initialValue: 0)
419+
private let nextSignpostID: Atomic<Int> = Atomic(0)
418420

419421
/// A type that is API-compatible to `OSLogMessage` for all uses within sourcekit-lsp.
420422
///
@@ -427,7 +429,7 @@ package struct NonDarwinSignposter: Sendable {
427429
}
428430

429431
package func makeSignpostID() -> NonDarwinSignpostID {
430-
return NonDarwinSignpostID(id: nextSignpostID.fetchAndIncrement())
432+
return NonDarwinSignpostID(id: nextSignpostID.add(1, ordering: .sequentiallyConsistent).oldValue)
431433
}
432434

433435
package func beginInterval(

0 commit comments

Comments
 (0)