Skip to content

Commit 26233b0

Browse files
committed
Clean up internal properties by adding leading underscores, refine availability to a TBD marker macro, and break at 80 lines to match style
1 parent ab72770 commit 26233b0

File tree

5 files changed

+168
-69
lines changed

5 files changed

+168
-69
lines changed

stdlib/public/Concurrency/Clock.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212
import Swift
1313

14-
@available(SwiftStdlib 5.1, *)
14+
@available(SwiftStdlib 9999, *)
1515
public protocol Clock: Sendable {
1616
associatedtype Instant: InstantProtocol
1717

@@ -22,7 +22,7 @@ public protocol Clock: Sendable {
2222
}
2323

2424

25-
@available(SwiftStdlib 5.1, *)
25+
@available(SwiftStdlib 9999, *)
2626
extension Clock {
2727
public func measure(_ work: () throws -> Void) rethrows -> Instant.Interval {
2828
let start = now
@@ -41,23 +41,23 @@ extension Clock {
4141
}
4242
}
4343

44-
@available(SwiftStdlib 5.1, *)
44+
@available(SwiftStdlib 9999, *)
4545
@usableFromInline
4646
enum swift_clock_id: Int32 {
4747
case continuous = 1
4848
case realtime = 2
4949
case suspending = 3
5050
}
5151

52-
@available(SwiftStdlib 5.1, *)
52+
@available(SwiftStdlib 9999, *)
5353
@_silgen_name("swift_get_time")
5454
@usableFromInline
5555
internal func _getTime(
5656
seconds: UnsafeMutablePointer<Int64>,
5757
nanoseconds: UnsafeMutablePointer<Int64>,
5858
clock: swift_clock_id)
5959

60-
@available(SwiftStdlib 5.1, *)
60+
@available(SwiftStdlib 9999, *)
6161
@_silgen_name("swift_get_clock_res")
6262
@usableFromInline
6363
internal func _getClockRes(

stdlib/public/Concurrency/ContinuousClock.swift

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,26 @@
1111
//===----------------------------------------------------------------------===//
1212
import Swift
1313

14-
@available(SwiftStdlib 5.1, *)
14+
@available(SwiftStdlib 9999, *)
1515
public struct ContinuousClock {
1616
public struct Instant: Codable, Sendable {
17-
var value: Duration
17+
internal var _value: Duration
1818

19-
init(_ value: Duration) {
20-
self.value = value
19+
internal init(_value: Duration) {
20+
self._value = _value
2121
}
2222
}
2323

2424
public init() { }
2525
}
2626

27-
@available(SwiftStdlib 5.1, *)
27+
@available(SwiftStdlib 9999, *)
2828
extension Clock where Self == ContinuousClock {
29-
@available(SwiftStdlib 5.1, *)
29+
@available(SwiftStdlib 9999, *)
3030
public static var continuous: ContinuousClock { return ContinuousClock() }
3131
}
3232

33-
@available(SwiftStdlib 5.1, *)
33+
@available(SwiftStdlib 9999, *)
3434
extension ContinuousClock: Clock {
3535
public var now: ContinuousClock.Instant {
3636
ContinuousClock.now
@@ -53,45 +53,45 @@ extension ContinuousClock: Clock {
5353
seconds: &seconds,
5454
nanoseconds: &nanoseconds,
5555
clock: .continuous)
56-
return ContinuousClock.Instant(
56+
return ContinuousClock.Instant(_value:
5757
.seconds(seconds) + .nanoseconds(nanoseconds))
5858
}
5959

6060
public func sleep(
6161
until deadline: Instant, tolerance: Duration? = nil
6262
) async throws {
63-
try await Task.sleep(until:
64-
deadline.value.seconds, deadline.value.nanoseconds,
63+
try await Task._sleep(until:
64+
deadline._value.seconds, deadline._value.nanoseconds,
6565
tolerance: tolerance,
6666
clock: .continuous)
6767
}
6868
}
6969

70-
@available(SwiftStdlib 5.1, *)
70+
@available(SwiftStdlib 9999, *)
7171
extension ContinuousClock.Instant: InstantProtocol {
7272
public static var now: ContinuousClock.Instant { ContinuousClock.now }
7373

7474
public func advanced(by duration: Duration) -> ContinuousClock.Instant {
75-
return ContinuousClock.Instant(value + duration)
75+
return ContinuousClock.Instant(_value: _value + duration)
7676
}
7777

7878
public func duration(to other: ContinuousClock.Instant) -> Duration {
79-
other.value - value
79+
other._value - _value
8080
}
8181

8282
public func hash(into hasher: inout Hasher) {
83-
hasher.combine(value)
83+
hasher.combine(_value)
8484
}
8585

8686
public static func == (
8787
_ lhs: ContinuousClock.Instant, _ rhs: ContinuousClock.Instant
8888
) -> Bool {
89-
return lhs.value == rhs.value
89+
return lhs._value == rhs._value
9090
}
9191

9292
public static func < (
9393
_ lhs: ContinuousClock.Instant, _ rhs: ContinuousClock.Instant
9494
) -> Bool {
95-
return lhs.value < rhs.value
95+
return lhs._value < rhs._value
9696
}
9797
}

stdlib/public/Concurrency/SuspendingClock.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@
1111
//===----------------------------------------------------------------------===//
1212
import Swift
1313

14-
@available(SwiftStdlib 5.1, *)
14+
@available(SwiftStdlib 9999, *)
1515
public struct SuspendingClock {
1616
public struct Instant: Codable, Sendable {
17-
var value: Duration
17+
internal var _value: Duration
1818

19-
init(_ value: Duration) {
20-
self.value = value
19+
internal init(_value: Duration) {
20+
self._value = _value
2121
}
2222
}
2323

2424
public init() { }
2525
}
2626

27-
@available(SwiftStdlib 5.1, *)
27+
@available(SwiftStdlib 9999, *)
2828
extension Clock where Self == SuspendingClock {
2929
public static var suspending: SuspendingClock { return SuspendingClock() }
3030
}
3131

32-
@available(SwiftStdlib 5.1, *)
32+
@available(SwiftStdlib 9999, *)
3333
extension SuspendingClock: Clock {
3434
public var now: SuspendingClock.Instant {
3535
SuspendingClock.now
@@ -42,7 +42,7 @@ extension SuspendingClock: Clock {
4242
seconds: &seconds,
4343
nanoseconds: &nanoseconds,
4444
clock: .continuous)
45-
return SuspendingClock.Instant(
45+
return SuspendingClock.Instant(_value:
4646
.seconds(seconds) + .nanoseconds(nanoseconds))
4747
}
4848

@@ -59,39 +59,39 @@ extension SuspendingClock: Clock {
5959
public func sleep(
6060
until deadline: Instant, tolerance: Duration? = nil
6161
) async throws {
62-
try await Task.sleep(until:
63-
deadline.value.seconds, deadline.value.nanoseconds,
62+
try await Task._sleep(until:
63+
deadline._value.seconds, deadline._value.nanoseconds,
6464
tolerance: tolerance,
6565
clock: .suspending)
6666
}
6767
}
6868

69-
@available(SwiftStdlib 5.1, *)
69+
@available(SwiftStdlib 9999, *)
7070
extension SuspendingClock.Instant: InstantProtocol {
7171
public static var now: SuspendingClock.Instant { SuspendingClock().now }
7272

7373
public func advanced(by duration: Duration) -> SuspendingClock.Instant {
74-
SuspendingClock.Instant(value + duration)
74+
SuspendingClock.Instant(_value: _value + duration)
7575
}
7676

7777
public func duration(to other: SuspendingClock.Instant) -> Duration {
78-
other.value - value
78+
other._value - _value
7979
}
8080

8181
public func hash(into hasher: inout Hasher) {
82-
hasher.combine(value)
82+
hasher.combine(_value)
8383
}
8484

8585
public static func == (
8686
_ lhs: SuspendingClock.Instant, _ rhs: SuspendingClock.Instant
8787
) -> Bool {
88-
return lhs.value == rhs.value
88+
return lhs._value == rhs._value
8989
}
9090

9191
public static func < (
9292
_ lhs: SuspendingClock.Instant, _ rhs: SuspendingClock.Instant
9393
) -> Bool {
94-
return lhs.value < rhs.value
94+
return lhs._value < rhs._value
9595
}
9696
}
9797

stdlib/public/Concurrency/TaskSleep.swift

Lines changed: 104 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ extension Task where Success == Never, Failure == Never {
2020
///
2121
/// This function doesn't block the underlying thread.
2222
public static func sleep(_ duration: UInt64) async {
23-
return await Builtin.withUnsafeContinuation { (continuation: Builtin.RawUnsafeContinuation) -> Void in
23+
return await Builtin.withUnsafeContinuation {
24+
(continuation: Builtin.RawUnsafeContinuation) -> Void in
2425
let job = _taskCreateNullaryContinuationJob(
2526
priority: Int(Task.currentPriority.rawValue),
2627
continuation: continuation)
@@ -201,11 +202,104 @@ extension Task where Success == Never, Failure == Never {
201202
///
202203
/// This function doesn't block the underlying thread.
203204
public static func sleep(nanoseconds duration: UInt64) async throws {
204-
let clock = ContinuousClock()
205-
try await Task.sleep(until: clock.now + .nanoseconds(duration), clock: clock)
205+
// Allocate storage for the storage word.
206+
let wordPtr = UnsafeMutablePointer<Builtin.Word>.allocate(capacity: 1)
207+
208+
// Initialize the flag word to "not started", which means the continuation
209+
// has neither been created nor completed.
210+
Builtin.atomicstore_seqcst_Word(
211+
wordPtr._rawValue, SleepState.notStarted.word._builtinWordValue)
212+
213+
do {
214+
// Install a cancellation handler to resume the continuation by
215+
// throwing CancellationError.
216+
try await withTaskCancellationHandler {
217+
let _: () = try await withUnsafeThrowingContinuation { continuation in
218+
while true {
219+
let state = SleepState(loading: wordPtr)
220+
switch state {
221+
case .notStarted:
222+
// The word that describes the active continuation state.
223+
let continuationWord =
224+
SleepState.activeContinuation(continuation).word
225+
226+
// Try to swap in the continuation word.
227+
let (_, won) = Builtin.cmpxchg_seqcst_seqcst_Word(
228+
wordPtr._rawValue,
229+
state.word._builtinWordValue,
230+
continuationWord._builtinWordValue)
231+
if !Bool(_builtinBooleanLiteral: won) {
232+
// Keep trying!
233+
continue
234+
}
235+
236+
// Create a task that resumes the continuation normally if it
237+
// finishes first. Enqueue it directly with the delay, so it fires
238+
// when we're done sleeping.
239+
let sleepTaskFlags = taskCreateFlags(
240+
priority: nil, isChildTask: false, copyTaskLocals: false,
241+
inheritContext: false, enqueueJob: false,
242+
addPendingGroupTaskUnconditionally: false)
243+
let (sleepTask, _) = Builtin.createAsyncTask(sleepTaskFlags) {
244+
onSleepWake(wordPtr)
245+
}
246+
_enqueueJobGlobalWithDelay(
247+
duration, Builtin.convertTaskToJob(sleepTask))
248+
return
249+
250+
case .activeContinuation, .finished:
251+
fatalError("Impossible to have multiple active continuations")
252+
253+
case .cancelled:
254+
fatalError("Impossible to have cancelled before we began")
255+
256+
case .cancelledBeforeStarted:
257+
// Finish the continuation normally. We'll throw later, after
258+
// we clean up.
259+
continuation.resume()
260+
return
261+
}
262+
}
263+
}
264+
} onCancel: {
265+
onSleepCancel(wordPtr)
266+
}
267+
268+
// Determine whether we got cancelled before we even started.
269+
let cancelledBeforeStarted: Bool
270+
switch SleepState(loading: wordPtr) {
271+
case .notStarted, .activeContinuation, .cancelled:
272+
fatalError("Invalid state for non-cancelled sleep task")
273+
274+
case .cancelledBeforeStarted:
275+
cancelledBeforeStarted = true
276+
277+
case .finished:
278+
cancelledBeforeStarted = false
279+
}
280+
281+
// We got here without being cancelled, so deallocate the storage for
282+
// the flag word and continuation.
283+
wordPtr.deallocate()
284+
285+
// If we got cancelled before we even started, through the cancellation
286+
// error now.
287+
if cancelledBeforeStarted {
288+
throw _Concurrency.CancellationError()
289+
}
290+
} catch {
291+
// The task was cancelled; propagate the error. The "on wake" task is
292+
// responsible for deallocating the flag word and continuation, if it's
293+
// still running.
294+
throw error
295+
}
206296
}
207297

208-
static func sleep(until seconds: Int64, _ nanoseconds: Int64, tolerance: Duration?, clock: swift_clock_id) async throws {
298+
@available(SwiftStdlib 9999, *)
299+
internal static func _sleep(
300+
until seconds: Int64, _ nanoseconds: Int64,
301+
tolerance: Duration?,
302+
clock: swift_clock_id) async throws {
209303
// Allocate storage for the storage word.
210304
let wordPtr = UnsafeMutablePointer<Builtin.Word>.allocate(capacity: 1)
211305

@@ -303,7 +397,12 @@ extension Task where Success == Never, Failure == Never {
303397
}
304398
}
305399

306-
public static func sleep<C: Clock>(until deadine: C.Instant, tolerance: C.Instant.Interval? = nil, clock: C) async throws {
400+
@available(SwiftStdlib 9999, *)
401+
public static func sleep<C: Clock>(
402+
until deadine: C.Instant,
403+
tolerance: C.Instant.Interval? = nil,
404+
clock: C
405+
) async throws {
307406
try await clock.sleep(until: deadine, tolerance: tolerance)
308407
}
309408
}

0 commit comments

Comments
 (0)