-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Concurrency] Updates after second SE pitch. #82456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
al45tair
wants to merge
8
commits into
swiftlang:main
Choose a base branch
from
al45tair:concurrency-updates
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+721
−862
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
c94afe4
[Concurrency] Updates after second SE pitch.
al45tair 4ef736b
[Concurrency] Add implementations of run and enqueue for built-in clo…
al45tair c93a898
[Concurrency] Remove canonicalization code.
al45tair 7a858f5
[Concurrency] Fix CooperativeExecutor to not loop forever.
al45tair 006efce
[Concurrency] Add a couple of comments.
al45tair 658cf60
[SILGen][Concurrency] Improve DefaultExecutorFactory lookup.
al45tair 262f07a
[Concurrency] Don't expose Dispatch or CF executors directly.
al45tair 15edb64
[Concurrency] Update documentation comment formatting.
al45tair File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -40,51 +40,61 @@ public protocol Clock<Duration>: Sendable { | |||||
|
||||||
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY | ||||||
func sleep(until deadline: Instant, tolerance: Instant.Duration?) async throws | ||||||
#endif | ||||||
|
||||||
/// The traits associated with this clock instance. | ||||||
@available(StdlibDeploymentTarget 6.2, *) | ||||||
var traits: ClockTraits { get } | ||||||
|
||||||
/// Convert a Clock-specific Duration to a Swift Duration | ||||||
/// Run the given job on an unspecified executor at some point | ||||||
/// after the given instant. | ||||||
/// | ||||||
/// Some clocks may define `C.Duration` to be something other than a | ||||||
/// `Swift.Duration`, but that makes it tricky to convert timestamps | ||||||
/// between clocks, which is something we want to be able to support. | ||||||
/// This method will convert whatever `C.Duration` is to a `Swift.Duration`. | ||||||
/// - Parameters: | ||||||
/// | ||||||
/// Parameters: | ||||||
/// - job: The job we wish to run | ||||||
/// - instant: The time at which we would like it to run. | ||||||
/// - tolerance: The ideal maximum delay we are willing to tolerate. | ||||||
/// | ||||||
/// - from duration: The `Duration` to convert | ||||||
/// | ||||||
/// Returns: A `Swift.Duration` representing the equivalent duration, or | ||||||
/// `nil` if this function is not supported. | ||||||
@available(StdlibDeploymentTarget 6.2, *) | ||||||
func convert(from duration: Duration) -> Swift.Duration? | ||||||
func run(_ job: consuming ExecutorJob, | ||||||
at instant: Instant, tolerance: Duration?) | ||||||
|
||||||
/// Convert a Swift Duration to a Clock-specific Duration | ||||||
/// Enqueue the given job on the specified executor at some point after the | ||||||
/// given instant. | ||||||
/// | ||||||
/// The default implementation uses the `run` method to trigger a job that | ||||||
/// does `executor.enqueue(job)`. If a particular `Clock` knows that the | ||||||
/// executor it has been asked to use is the same one that it will run jobs | ||||||
/// on, it can short-circuit this behaviour and directly use `run` with | ||||||
/// the original job. | ||||||
/// | ||||||
/// Parameters: | ||||||
/// - Parameters: | ||||||
/// | ||||||
/// - from duration: The `Swift.Duration` to convert. | ||||||
/// - job: The job we wish to run | ||||||
/// - executor: The executor on which we would like it to run. | ||||||
/// - instant: The time at which we would like it to run. | ||||||
/// - tolerance: The ideal maximum delay we are willing to tolerate. | ||||||
/// | ||||||
/// Returns: A `Duration` representing the equivalent duration, or | ||||||
/// `nil` if this function is not supported. | ||||||
@available(StdlibDeploymentTarget 6.2, *) | ||||||
func convert(from duration: Swift.Duration) -> Duration? | ||||||
func enqueue(_ job: consuming ExecutorJob, | ||||||
on executor: some Executor, | ||||||
at instant: Instant, tolerance: Duration?) | ||||||
#endif | ||||||
} | ||||||
|
||||||
/// Convert an `Instant` from some other clock's `Instant` | ||||||
/// | ||||||
/// Parameters: | ||||||
/// | ||||||
/// - instant: The instant to convert. | ||||||
// - from clock: The clock to convert from. | ||||||
/// | ||||||
/// Returns: An `Instant` representing the equivalent instant, or | ||||||
/// `nil` if this function is not supported. | ||||||
extension Clock { | ||||||
// The default implementation works by creating a trampoline and calling | ||||||
// the run() method. | ||||||
@available(StdlibDeploymentTarget 6.2, *) | ||||||
public func enqueue(_ job: consuming ExecutorJob, | ||||||
on executor: some Executor, | ||||||
at instant: Instant, tolerance: Duration?) { | ||||||
let trampoline = job.createTrampoline(to: executor) | ||||||
run(trampoline, at: instant, tolerance: tolerance) | ||||||
} | ||||||
|
||||||
// Clocks that do not implement run will fatalError() if you try to use | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
maybe? "implement run" sounds a bit weird mid-sentence |
||||||
// them with an executor that does not understand them. | ||||||
@available(StdlibDeploymentTarget 6.2, *) | ||||||
func convert<OtherClock: Clock>(instant: OtherClock.Instant, | ||||||
from clock: OtherClock) -> Instant? | ||||||
public func run(_ job: consuming ExecutorJob, | ||||||
at instant: Instant, tolerance: Duration?) { | ||||||
fatalError("\(Self.self) does not implement run(_:at:tolerance:).") | ||||||
} | ||||||
} | ||||||
|
||||||
@available(StdlibDeploymentTarget 5.7, *) | ||||||
|
@@ -140,44 +150,6 @@ extension Clock { | |||||
} | ||||||
} | ||||||
|
||||||
@available(StdlibDeploymentTarget 6.2, *) | ||||||
extension Clock { | ||||||
// For compatibility, return `nil` if this is not implemented | ||||||
public func convert(from duration: Duration) -> Swift.Duration? { | ||||||
return nil | ||||||
} | ||||||
|
||||||
public func convert(from duration: Swift.Duration) -> Duration? { | ||||||
return nil | ||||||
} | ||||||
|
||||||
public func convert<OtherClock: Clock>(instant: OtherClock.Instant, | ||||||
from clock: OtherClock) -> Instant? { | ||||||
let ourNow = now | ||||||
let otherNow = clock.now | ||||||
let otherDuration = otherNow.duration(to: instant) | ||||||
|
||||||
// Convert to `Swift.Duration` | ||||||
guard let duration = clock.convert(from: otherDuration) else { | ||||||
return nil | ||||||
} | ||||||
|
||||||
// Convert from `Swift.Duration` | ||||||
guard let ourDuration = convert(from: duration) else { | ||||||
return nil | ||||||
} | ||||||
|
||||||
return ourNow.advanced(by: ourDuration) | ||||||
} | ||||||
} | ||||||
|
||||||
@available(StdlibDeploymentTarget 6.2, *) | ||||||
extension Clock where Duration == Swift.Duration { | ||||||
public func convert(from duration: Duration) -> Duration? { | ||||||
return duration | ||||||
} | ||||||
} | ||||||
|
||||||
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY | ||||||
@available(StdlibDeploymentTarget 5.7, *) | ||||||
extension Clock { | ||||||
|
@@ -196,47 +168,10 @@ extension Clock { | |||||
} | ||||||
#endif | ||||||
|
||||||
/// Represents traits of a particular Clock implementation. | ||||||
/// | ||||||
/// Clocks may be of a number of different varieties; executors will likely | ||||||
/// have specific clocks that they can use to schedule jobs, and will | ||||||
/// therefore need to be able to convert timestamps to an appropriate clock | ||||||
/// when asked to enqueue a job with a delay or deadline. | ||||||
/// | ||||||
/// Choosing a clock in general requires the ability to tell which of their | ||||||
/// clocks best matches the clock that the user is trying to specify a | ||||||
/// time or delay in. Executors are expected to do this on a best effort | ||||||
/// basis. | ||||||
@available(StdlibDeploymentTarget 6.2, *) | ||||||
public struct ClockTraits: OptionSet { | ||||||
public let rawValue: UInt32 | ||||||
|
||||||
public init(rawValue: UInt32) { | ||||||
self.rawValue = rawValue | ||||||
} | ||||||
|
||||||
/// Clocks with this trait continue running while the machine is asleep. | ||||||
public static let continuous = ClockTraits(rawValue: 1 << 0) | ||||||
|
||||||
/// Indicates that a clock's time will only ever increase. | ||||||
public static let monotonic = ClockTraits(rawValue: 1 << 1) | ||||||
|
||||||
/// Clocks with this trait are tied to "wall time". | ||||||
public static let wallTime = ClockTraits(rawValue: 1 << 2) | ||||||
} | ||||||
|
||||||
@available(StdlibDeploymentTarget 6.2, *) | ||||||
extension Clock { | ||||||
/// The traits associated with this clock instance. | ||||||
@available(StdlibDeploymentTarget 6.2, *) | ||||||
public var traits: ClockTraits { | ||||||
return [] | ||||||
} | ||||||
} | ||||||
|
||||||
enum _ClockID: Int32 { | ||||||
case continuous = 1 | ||||||
case suspending = 2 | ||||||
case walltime = 3 | ||||||
} | ||||||
|
||||||
@available(StdlibDeploymentTarget 5.7, *) | ||||||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor
maybe worth ref like that?