@@ -503,6 +503,37 @@ extension Task {
503503 }
504504}
505505
506+ // ==== Voluntary Suspension -----------------------------------------------------
507+ extension Task {
508+
509+ /// Explicitly suspend the current task, potentially giving up execution actor
510+ /// of current actor/task, allowing other tasks to execute.
511+ ///
512+ /// This is not a perfect cure for starvation;
513+ /// if the task is the highest-priority task in the system, it might go
514+ /// immediately back to executing.
515+ public static func yield( ) async {
516+ // Prepare the job flags
517+ var flags = JobFlags ( )
518+ flags. kind = . task
519+ flags. priority = . default
520+ flags. isFuture = true
521+
522+ // Create the asynchronous task future, it will do nothing, but simply serves
523+ // as a way for us to yield our execution until the executor gets to it and
524+ // resumes us.
525+ // FIXME: This should be an empty closure instead. Returning `0` here is
526+ // a workaround for rdar://74957357
527+ // TODO: consider if it would be useful for this task to be a child task
528+ let ( task, _) = Builtin . createAsyncTaskFuture ( flags. bits, nil , { return 0 } )
529+
530+ // Enqueue the resulting job.
531+ _enqueueJobGlobal ( Builtin . convertTaskToJob ( task) )
532+
533+ let _ = await Handle < Int , Never > ( task) . get ( )
534+ }
535+ }
536+
506537// ==== UnsafeCurrentTask ------------------------------------------------------
507538
508539/// Calls the given closure with the with the "current" task in which this
0 commit comments