@@ -40,52 +40,64 @@ public protocol Clock<Duration>: Sendable {
4040
4141#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY 
4242  func  sleep( until deadline:  Instant ,  tolerance:  Instant . Duration ? )  async  throws 
43- #endif 
44- 
45-   /// The traits associated with this clock instance.
46-   @available ( StdlibDeploymentTarget 6 . 2 ,  * )  
47-   var  traits :  ClockTraits  {  get  } 
4843
49-   /// Convert a Clock-specific Duration to a Swift Duration
50-   ///
51-   /// Some clocks may define `C.Duration` to be something other than a
52-   /// `Swift.Duration`, but that makes it tricky to convert timestamps
53-   /// between clocks, which is something we want to be able to support.
54-   /// This method will convert whatever `C.Duration` is to a `Swift.Duration`.
44+   /// Run the given job on an unspecified executor at some point
45+   /// after the given instant.
5546  ///
5647  /// Parameters:
5748  ///
58-   /// - from duration: The `Duration` to convert
49+   /// - job:         The job we wish to run
50+   /// - at instant:  The time at which we would like it to run.
51+   /// - tolerance:   The ideal maximum delay we are willing to tolerate.
5952  ///
60-   /// Returns: A `Swift.Duration` representing the equivalent duration, or
61-   ///          `nil` if this function is not supported.
6253  @available ( StdlibDeploymentTarget 6 . 2 ,  * )  
63-   func  convert( from duration:  Duration )  ->  Swift . Duration ? 
54+   func  run( _ job:  consuming  ExecutorJob , 
55+            at instant:  Instant ,  tolerance:  Duration ? ) 
6456
65-   /// Convert a Swift Duration to a Clock-specific Duration
57+   /// Enqueue the given job on the specified executor at some point after the
58+   /// given instant.
59+   ///
60+   /// The default implementation uses the `run` method to trigger a job that
61+   /// does `executor.enqueue(job)`.  If a particular `Clock` knows that the
62+   /// executor it has been asked to use is the same one that it will run jobs
63+   /// on, it can short-circuit this behaviour and directly use `run` with
64+   /// the original job.
6665  ///
6766  /// Parameters:
6867  ///
69-   /// - from duration: The `Swift.Duration` to convert.
68+   /// - job:         The job we wish to run
69+   /// - on executor: The executor on which we would like it to run.
70+   /// - at instant:  The time at which we would like it to run.
71+   /// - tolerance:   The ideal maximum delay we are willing to tolerate.
7072  ///
71-   /// Returns: A `Duration` representing the equivalent duration, or
72-   ///          `nil` if this function is not supported.
7373  @available ( StdlibDeploymentTarget 6 . 2 ,  * )  
74-   func  convert( from duration:  Swift . Duration )  ->  Duration ? 
74+   func  enqueue( _ job:  consuming  ExecutorJob , 
75+                on executor:  some  Executor , 
76+                at instant:  Instant ,  tolerance:  Duration ? ) 
77+ #endif 
78+ } 
7579
76-   /// Convert an `Instant` from some other clock's `Instant`
77-   ///
78-   /// Parameters:
79-   ///
80-   /// - instant:    The instant to convert.
81-   //  - from clock: The clock to convert from.
82-   ///
83-   /// Returns: An `Instant` representing the equivalent instant, or
84-   ///          `nil` if this function is not supported.
80+ #if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY 
81+ extension  Clock  { 
82+   // The default implementation works by creating a trampoline and calling
83+   // the run() method.
8584  @available ( StdlibDeploymentTarget 6 . 2 ,  * )  
86-   func  convert< OtherClock:  Clock > ( instant:  OtherClock . Instant , 
87-                                   from clock:  OtherClock )  ->  Instant ? 
85+   public  func  enqueue( _ job:  consuming  ExecutorJob , 
86+                       on executor:  some  Executor , 
87+                       at instant:  Instant ,  tolerance:  Duration ? )  { 
88+     let  trampoline  =  job. createTrampoline ( to:  executor) 
89+     run ( trampoline,  at:  instant,  tolerance:  tolerance) 
90+   } 
91+ 
92+   // Clocks that do not implement run will fatalError() if you try to use
93+   // them with an executor that does not understand them.
94+   @available ( StdlibDeploymentTarget 6 . 2 ,  * )  
95+   public  func  run( _ job:  consuming  ExecutorJob , 
96+                   at instant:  Instant ,  tolerance:  Duration ? )  { 
97+     fatalError ( " \( Self . self)  does not implement run(_:at:tolerance:). " ) 
98+   } 
8899} 
100+ #endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY 
89101
90102@available ( StdlibDeploymentTarget 5 . 7 ,  * )  
91103extension  Clock  { 
@@ -140,44 +152,6 @@ extension Clock {
140152  } 
141153} 
142154
143- @available ( StdlibDeploymentTarget 6 . 2 ,  * )  
144- extension  Clock  { 
145-   // For compatibility, return `nil` if this is not implemented
146-   public  func  convert( from duration:  Duration )  ->  Swift . Duration ?   { 
147-     return  nil 
148-   } 
149- 
150-   public  func  convert( from duration:  Swift . Duration )  ->  Duration ?   { 
151-     return  nil 
152-   } 
153- 
154-   public  func  convert< OtherClock:  Clock > ( instant:  OtherClock . Instant , 
155-                                   from clock:  OtherClock )  ->  Instant ?   { 
156-     let  ourNow  =  now
157-     let  otherNow  =  clock. now
158-     let  otherDuration  =  otherNow. duration ( to:  instant) 
159- 
160-     // Convert to `Swift.Duration`
161-     guard  let  duration =  clock. convert ( from:  otherDuration)  else  { 
162-       return  nil 
163-     } 
164- 
165-     // Convert from `Swift.Duration`
166-     guard  let  ourDuration =  convert ( from:  duration)  else  { 
167-       return  nil 
168-     } 
169- 
170-     return  ourNow. advanced ( by:  ourDuration) 
171-   } 
172- } 
173- 
174- @available ( StdlibDeploymentTarget 6 . 2 ,  * )  
175- extension  Clock  where  Duration ==  Swift . Duration  { 
176-   public  func  convert( from duration:  Duration )  ->  Duration ?   { 
177-     return  duration
178-   } 
179- } 
180- 
181155#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY 
182156@available ( StdlibDeploymentTarget 5 . 7 ,  * )  
183157extension  Clock  { 
@@ -196,47 +170,10 @@ extension Clock {
196170} 
197171#endif 
198172
199- /// Represents traits of a particular Clock implementation.
200- ///
201- /// Clocks may be of a number of different varieties; executors will likely
202- /// have specific clocks that they can use to schedule jobs, and will
203- /// therefore need to be able to convert timestamps to an appropriate clock
204- /// when asked to enqueue a job with a delay or deadline.
205- ///
206- /// Choosing a clock in general requires the ability to tell which of their
207- /// clocks best matches the clock that the user is trying to specify a
208- /// time or delay in.  Executors are expected to do this on a best effort
209- /// basis.
210- @available ( StdlibDeploymentTarget 6 . 2 ,  * )  
211- public  struct  ClockTraits :  OptionSet  { 
212-   public  let  rawValue :  UInt32 
213- 
214-   public  init ( rawValue:  UInt32 )  { 
215-     self . rawValue =  rawValue
216-   } 
217- 
218-   /// Clocks with this trait continue running while the machine is asleep.
219-   public  static  let  continuous   =  ClockTraits ( rawValue:  1  << 0 ) 
220- 
221-   /// Indicates that a clock's time will only ever increase.
222-   public  static  let  monotonic   =  ClockTraits ( rawValue:  1  << 1 ) 
223- 
224-   /// Clocks with this trait are tied to "wall time".
225-   public  static  let  wallTime   =  ClockTraits ( rawValue:  1  << 2 ) 
226- } 
227- 
228- @available ( StdlibDeploymentTarget 6 . 2 ,  * )  
229- extension  Clock  { 
230-   /// The traits associated with this clock instance.
231-   @available ( StdlibDeploymentTarget 6 . 2 ,  * )  
232-   public  var  traits :  ClockTraits  { 
233-     return  [ ] 
234-   } 
235- } 
236- 
237173enum  _ClockID :  Int32  { 
238174  case  continuous =  1 
239175  case  suspending =  2 
176+   case  walltime =  3 
240177} 
241178
242179@available ( StdlibDeploymentTarget 5 . 7 ,  * )  
0 commit comments