Skip to content

Commit 204dd33

Browse files
committed
Heap allocate our atomics
We used C atomics but these were allocated as Swift variables. Even thought they were atomic, concurrent accesses to them could violate Swift’s exclusivity laws, raising thread sanitizer errors. Allocate the C atomics using malloc to fix this problem. rdar://129170128
1 parent cec73bb commit 204dd33

File tree

16 files changed

+105
-76
lines changed

16 files changed

+105
-76
lines changed

Package.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ let package = Package(
108108
.target(
109109
name: "InProcessClient",
110110
dependencies: [
111-
"CAtomics",
112111
"LanguageServerProtocol",
113112
"LSPLogging",
114113
"SKCore",
@@ -193,7 +192,6 @@ let package = Package(
193192
.target(
194193
name: "SemanticIndex",
195194
dependencies: [
196-
"CAtomics",
197195
"LanguageServerProtocol",
198196
"LSPLogging",
199197
"SKCore",
@@ -218,7 +216,6 @@ let package = Package(
218216
name: "SKCore",
219217
dependencies: [
220218
"BuildServerProtocol",
221-
"CAtomics",
222219
"LanguageServerProtocol",
223220
"LanguageServerProtocolJSONRPC",
224221
"LSPLogging",
@@ -247,10 +244,11 @@ let package = Package(
247244
.target(
248245
name: "SKSupport",
249246
dependencies: [
250-
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
247+
"CAtomics",
251248
"LanguageServerProtocol",
252249
"LSPLogging",
253250
"SwiftExtensions",
251+
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
254252
],
255253
exclude: ["CMakeLists.txt"],
256254
swiftSettings: [.enableExperimentalFeature("StrictConcurrency")]
@@ -350,7 +348,6 @@ let package = Package(
350348
name: "SourceKitLSP",
351349
dependencies: [
352350
"BuildServerProtocol",
353-
"CAtomics",
354351
"LanguageServerProtocol",
355352
"LanguageServerProtocolJSONRPC",
356353
"LSPLogging",
@@ -378,7 +375,6 @@ let package = Package(
378375
name: "SourceKitLSPTests",
379376
dependencies: [
380377
"BuildServerProtocol",
381-
"CAtomics",
382378
"LSPLogging",
383379
"LSPTestSupport",
384380
"LanguageServerProtocol",

Sources/CAtomics/include/CAtomics.h

Lines changed: 12 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -16,79 +16,32 @@
1616
#include <stdbool.h>
1717
#include <stdint.h>
1818
#include <sys/types.h>
19-
20-
// MARK: - AtomicBool
21-
22-
typedef struct {
23-
_Atomic(bool) value;
24-
} AtomicBool;
25-
26-
__attribute__((swift_name("AtomicBool.init(initialValue:)")))
27-
static inline AtomicBool atomic_bool_create(bool initialValue) {
28-
AtomicBool atomic;
29-
atomic.value = initialValue;
30-
return atomic;
31-
}
32-
33-
__attribute__((swift_name("getter:AtomicBool.value(self:)")))
34-
static inline bool atomic_bool_get(AtomicBool *atomic) {
35-
return atomic->value;
36-
}
37-
38-
__attribute__((swift_name("setter:AtomicBool.value(self:_:)")))
39-
static inline void atomic_bool_set(AtomicBool *atomic, bool newValue) {
40-
atomic->value = newValue;
41-
}
42-
43-
// MARK: - AtomicUInt8
19+
#include <stdlib.h>
4420

4521
typedef struct {
46-
_Atomic(uint8_t) value;
47-
} AtomicUInt8;
22+
_Atomic(uint32_t) value;
23+
} CAtomicUInt32;
4824

49-
__attribute__((swift_name("AtomicUInt8.init(initialValue:)")))
50-
static inline AtomicUInt8 atomic_uint8_create(uint8_t initialValue) {
51-
AtomicUInt8 atomic;
52-
atomic.value = initialValue;
25+
static inline CAtomicUInt32 *_Nonnull atomic_uint32_create(uint32_t initialValue) {
26+
CAtomicUInt32 *atomic = malloc(sizeof(CAtomicUInt32));
27+
atomic->value = initialValue;
5328
return atomic;
5429
}
5530

56-
__attribute__((swift_name("getter:AtomicUInt8.value(self:)")))
57-
static inline uint8_t atomic_uint8_get(AtomicUInt8 *atomic) {
31+
static inline uint32_t atomic_uint32_get(CAtomicUInt32 *_Nonnull atomic) {
5832
return atomic->value;
5933
}
6034

61-
__attribute__((swift_name("setter:AtomicUInt8.value(self:_:)")))
62-
static inline void atomic_uint8_set(AtomicUInt8 *atomic, uint8_t newValue) {
35+
static inline void atomic_uint32_set(CAtomicUInt32 *_Nonnull atomic, uint32_t newValue) {
6336
atomic->value = newValue;
6437
}
6538

66-
// MARK: AtomicInt
67-
68-
typedef struct {
69-
_Atomic(int) value;
70-
} AtomicUInt32;
71-
72-
__attribute__((swift_name("AtomicUInt32.init(initialValue:)")))
73-
static inline AtomicUInt32 atomic_int_create(uint32_t initialValue) {
74-
AtomicUInt32 atomic;
75-
atomic.value = initialValue;
76-
return atomic;
77-
}
78-
79-
__attribute__((swift_name("getter:AtomicUInt32.value(self:)")))
80-
static inline uint32_t atomic_int_get(AtomicUInt32 *atomic) {
81-
return atomic->value;
82-
}
83-
84-
__attribute__((swift_name("setter:AtomicUInt32.value(self:_:)")))
85-
static inline void atomic_uint32_set(AtomicUInt32 *atomic, uint32_t newValue) {
86-
atomic->value = newValue;
39+
static inline uint32_t atomic_uint32_fetch_and_increment(CAtomicUInt32 *_Nonnull atomic) {
40+
return atomic->value++;
8741
}
8842

89-
__attribute__((swift_name("AtomicUInt32.fetchAndIncrement(self:)")))
90-
static inline uint32_t atomic_uint32_fetch_and_increment(AtomicUInt32 *atomic) {
91-
return atomic->value++;
43+
static inline void atomic_uint32_destroy(CAtomicUInt32 *_Nonnull atomic) {
44+
free(atomic);
9245
}
9346

9447
#endif // SOURCEKITLSP_CATOMICS_H

Sources/InProcessClient/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ set_target_properties(InProcessClient PROPERTIES
66
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
77

88
target_link_libraries(InProcessClient PUBLIC
9-
CAtomics
109
LanguageServerProtocol
1110
LSPLogging
1211
SKCore

Sources/InProcessClient/InProcessSourceKitLSPClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import CAtomics
1413
import LanguageServerProtocol
1514
import SKCore
15+
import SKSupport
1616
import SourceKitLSP
1717

1818
/// Launches a `SourceKitLSPServer` in-process and allows sending messages to it.

Sources/SKCore/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ set_target_properties(SKCore PROPERTIES
2323
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
2424
target_link_libraries(SKCore PUBLIC
2525
BuildServerProtocol
26-
CAtomics
2726
LanguageServerProtocol
2827
LanguageServerProtocolJSONRPC
2928
LSPLogging

Sources/SKCore/TaskScheduler.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import CAtomics
1413
import Foundation
1514
import LSPLogging
1615
import SKSupport

Sources/SKSupport/Atomics.swift

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import CAtomics
14+
15+
#if compiler(>=6.2)
16+
#warning("We should be able to use atomics in the stdlib when we raise the deployment target to require Swift 6")
17+
#endif
18+
19+
public class AtomicBool {
20+
private let atomic: UnsafeMutablePointer<CAtomicUInt32>
21+
22+
public init(initialValue: Bool) {
23+
self.atomic = atomic_uint32_create(initialValue ? 1 : 0)
24+
}
25+
26+
deinit {
27+
atomic_uint32_destroy(atomic)
28+
}
29+
30+
public var value: Bool {
31+
get {
32+
atomic_uint32_get(atomic) != 0
33+
}
34+
set {
35+
atomic_uint32_set(atomic, newValue ? 1 : 0)
36+
}
37+
}
38+
}
39+
40+
public class AtomicUInt8 {
41+
private let atomic: UnsafeMutablePointer<CAtomicUInt32>
42+
43+
public init(initialValue: UInt8) {
44+
self.atomic = atomic_uint32_create(UInt32(initialValue))
45+
}
46+
47+
deinit {
48+
atomic_uint32_destroy(atomic)
49+
}
50+
51+
public var value: UInt8 {
52+
get {
53+
UInt8(atomic_uint32_get(atomic))
54+
}
55+
set {
56+
atomic_uint32_set(atomic, UInt32(newValue))
57+
}
58+
}
59+
}
60+
61+
public class AtomicUInt32 {
62+
private let atomic: UnsafeMutablePointer<CAtomicUInt32>
63+
64+
public init(initialValue: UInt32) {
65+
self.atomic = atomic_uint32_create(initialValue)
66+
}
67+
68+
public var value: UInt32 {
69+
get {
70+
atomic_uint32_get(atomic)
71+
}
72+
set {
73+
atomic_uint32_set(atomic, newValue)
74+
}
75+
}
76+
77+
deinit {
78+
atomic_uint32_destroy(atomic)
79+
}
80+
81+
public func fetchAndIncrement() -> UInt32 {
82+
return atomic_uint32_fetch_and_increment(atomic)
83+
}
84+
}

Sources/SKSupport/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
add_library(SKSupport STATIC
3+
Atomics.swift
34
BuildConfiguration.swift
45
ByteString.swift
56
Connection+Send.swift
@@ -18,6 +19,7 @@ add_library(SKSupport STATIC
1819
set_target_properties(SKSupport PROPERTIES
1920
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
2021
target_link_libraries(SKSupport PRIVATE
22+
CAtomics
2123
LanguageServerProtocol
2224
LSPLogging
2325
SwiftExtensions

Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import Basics
1414
import Build
1515
import BuildServerProtocol
16-
import CAtomics
1716
import Dispatch
1817
import Foundation
1918
import LSPLogging

Sources/SKTestSupport/TestSourceKitLSPClient.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import CAtomics
1413
import Foundation
1514
import InProcessClient
1615
import LSPTestSupport

Sources/SemanticIndex/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_library(SemanticIndex STATIC
1212
set_target_properties(SemanticIndex PROPERTIES
1313
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
1414
target_link_libraries(SemanticIndex PRIVATE
15+
LanguageServerProtocol
1516
LSPLogging
1617
SKCore
1718
SwiftExtensions

Sources/SemanticIndex/PreparationTaskDescription.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import CAtomics
1413
import Foundation
1514
import LSPLogging
1615
import LanguageServerProtocol
1716
import SKCore
17+
import SKSupport
1818

1919
import struct TSCBasic.AbsolutePath
2020
import class TSCBasic.Process

Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import CAtomics
1413
import Foundation
1514
import LSPLogging
1615
import LanguageServerProtocol

Sources/SourceKitLSP/SourceKitLSPServer.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import BuildServerProtocol
14-
import CAtomics
1514
import Dispatch
1615
import Foundation
1716
import IndexStoreDB

Tests/SourceKitDTests/SourceKitDRegistryTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import CAtomics
1413
import LSPTestSupport
14+
import SKSupport
1515
import SourceKitD
1616
import TSCBasic
1717
import XCTest

Tests/SourceKitLSPTests/PullDiagnosticsTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import CAtomics
1413
import LSPTestSupport
1514
import LanguageServerProtocol
15+
import SKSupport
1616
import SKTestSupport
1717
import SourceKitLSP
1818
import XCTest

0 commit comments

Comments
 (0)