1515// / This file is included into GlobalExecutor.cpp only when
1616// / the cooperative global executor is enabled. It is expected to
1717// / declare the following functions:
18+ // / swift_task_asyncMainDrainQueueImpl
19+ // / swift_task_checkIsolatedImpl
20+ // / swift_task_donateThreadToGlobalExecutorUntilImpl
1821// / swift_task_enqueueGlobalImpl
22+ // / swift_task_enqueueGlobalWithDeadlineImpl
1923// / swift_task_enqueueGlobalWithDelayImpl
2024// / swift_task_enqueueMainExecutorImpl
21- // / swift_task_checkIsolatedImpl
25+ // / swift_task_getMainExecutorImpl
26+ // / swift_task_isMainExecutorImpl
2227// / as well as any cooperative-executor-specific functions in the runtime.
2328// /
2429// /===------------------------------------------------------------------===///
2530
26- #include " swift/Runtime/Concurrency .h"
31+ #include " swift/shims/Visibility .h"
2732
2833#include < chrono>
2934#ifndef SWIFT_THREADING_NONE
3944# define NSEC_PER_SEC 1000000000ull
4045#endif
4146
42- #include " ExecutorHooks .h"
47+ #include " ExecutorImpl .h"
4348
4449using namespace swift ;
4550
4651namespace {
4752
4853struct JobQueueTraits {
49- static Job *&storage (Job *cur) {
50- return reinterpret_cast <Job *&>(cur->SchedulerPrivate [0 ]);
54+ static SwiftJob *&storage (SwiftJob *cur) {
55+ return reinterpret_cast <SwiftJob *&>(cur->schedulerPrivate [0 ]);
5156 }
5257
53- static Job *getNext (Job *job) {
58+ static SwiftJob *getNext (SwiftJob *job) {
5459 return storage (job);
5560 }
56- static void setNext (Job *job, Job *next) {
61+ static void setNext (SwiftJob *job, SwiftJob *next) {
5762 storage (job) = next;
5863 }
59- enum { prioritiesCount = PriorityBucketCount };
60- static int getPriorityIndex (Job *job) {
61- return getPriorityBucketIndex (job-> getPriority ( ));
64+ enum { prioritiesCount = SwiftJobPriorityBucketCount };
65+ static int getPriorityIndex (SwiftJob *job) {
66+ return swift_priority_getBucketIndex ( swift_job_getPriority (job ));
6267 }
6368};
64- using JobPriorityQueue = PriorityQueue<Job *, JobQueueTraits>;
69+ using JobPriorityQueue = PriorityQueue<SwiftJob *, JobQueueTraits>;
6570
6671using JobDeadline = std::chrono::time_point<std::chrono::steady_clock>;
6772
6873template <bool = (sizeof (JobDeadline) <= sizeof (void *) &&
6974 alignof (JobDeadline) <= alignof (void *))>
7075struct JobDeadlineStorage ;
7176
72- // / Specialization for when JobDeadline fits in SchedulerPrivate .
77+ // / Specialization for when JobDeadline fits in schedulerPrivate .
7378template <>
7479struct JobDeadlineStorage <true > {
75- static JobDeadline &storage (Job *job) {
76- return reinterpret_cast <JobDeadline&>(job->SchedulerPrivate [1 ]);
80+ static JobDeadline &storage (SwiftJob *job) {
81+ return reinterpret_cast <JobDeadline&>(job->schedulerPrivate [1 ]);
7782 }
78- static JobDeadline get (Job *job) {
83+ static JobDeadline get (SwiftJob *job) {
7984 return storage (job);
8085 }
81- static void set (Job *job, JobDeadline deadline) {
86+ static void set (SwiftJob *job, JobDeadline deadline) {
8287 new (static_cast <void *>(&storage (job))) JobDeadline (deadline);
8388 }
84- static void destroy (Job *job) {
89+ static void destroy (SwiftJob *job) {
8590 storage (job).~JobDeadline ();
8691 }
8792};
8893
89- // / Specialization for when JobDeadline doesn't fit in SchedulerPrivate .
94+ // / Specialization for when JobDeadline doesn't fit in schedulerPrivate .
9095template <>
9196struct JobDeadlineStorage <false > {
92- static JobDeadline *&storage (Job *job) {
93- return reinterpret_cast <JobDeadline*&>(job->SchedulerPrivate [1 ]);
97+ static JobDeadline *&storage (SwiftJob *job) {
98+ return reinterpret_cast <JobDeadline*&>(job->schedulerPrivate [1 ]);
9499 }
95- static JobDeadline get (Job *job) {
100+ static JobDeadline get (SwiftJob *job) {
96101 return *storage (job);
97102 }
98- static void set (Job *job, JobDeadline deadline) {
103+ static void set (SwiftJob *job, JobDeadline deadline) {
99104 storage (job) = new JobDeadline (deadline);
100105 }
101- static void destroy (Job *job) {
106+ static void destroy (SwiftJob *job) {
102107 delete storage (job);
103108 }
104109};
105110
106111} // end anonymous namespace
107112
108113static JobPriorityQueue JobQueue;
109- static Job *DelayedJobQueue = nullptr ;
114+ static SwiftJob *DelayedJobQueue = nullptr ;
110115
111116// / Insert a job into the cooperative global queue.
112117SWIFT_CC (swift)
113- void swift:: swift_task_enqueueGlobalImpl(Job *job) {
118+ void swift_task_enqueueGlobalImpl(SwiftJob *job) {
114119 assert (job && " no job provided" );
115120 JobQueue.enqueue (job);
116121}
117122
118123// / Enqueues a task on the main executor.
119124SWIFT_CC (swift)
120- void swift:: swift_task_enqueueMainExecutorImpl(Job *job) {
125+ void swift_task_enqueueMainExecutorImpl(SwiftJob *job) {
121126 // The cooperative executor does not distinguish between the main
122127 // queue and the global queue.
123128 swift_task_enqueueGlobalImpl (job);
124129}
125130
126- static void insertDelayedJob (Job *newJob, JobDeadline deadline) {
127- Job **position = &DelayedJobQueue;
131+ static void insertDelayedJob (SwiftJob *newJob, JobDeadline deadline) {
132+ SwiftJob **position = &DelayedJobQueue;
128133 while (auto cur = *position) {
129134 // If we find a job with a later deadline, insert here.
130135 // Note that we maintain FIFO order.
@@ -142,14 +147,14 @@ static void insertDelayedJob(Job *newJob, JobDeadline deadline) {
142147}
143148
144149SWIFT_CC (swift)
145- void swift:: swift_task_checkIsolatedImpl(SerialExecutorRef executor) {
146- swift_task_invokeSwiftCheckIsolated (executor);
150+ void swift_task_checkIsolatedImpl(SwiftExecutorRef executor) {
151+ swift_executor_invokeSwiftCheckIsolated (executor);
147152}
148153
149154// / Insert a job into the cooperative global queue with a delay.
150155SWIFT_CC (swift)
151- void swift:: swift_task_enqueueGlobalWithDelayImpl(JobDelay delay,
152- Job *newJob) {
156+ void swift_task_enqueueGlobalWithDelayImpl(SwiftJobDelay delay,
157+ SwiftJob *newJob) {
153158 assert (newJob && " no job provided" );
154159
155160 auto deadline = std::chrono::steady_clock::now ()
@@ -161,18 +166,16 @@ void swift::swift_task_enqueueGlobalWithDelayImpl(JobDelay delay,
161166}
162167
163168SWIFT_CC (swift)
164- void swift:: swift_task_enqueueGlobalWithDeadlineImpl(long long sec,
165- long long nsec,
166- long long tsec,
167- long long tnsec,
168- int clock, Job *newJob) {
169+ void swift_task_enqueueGlobalWithDeadlineImpl(long long sec,
170+ long long nsec,
171+ long long tsec,
172+ long long tnsec,
173+ int clock, SwiftJob *newJob) {
169174 assert (newJob && " no job provided" );
170175
171- long long nowSec;
172- long long nowNsec;
173- swift_get_time (&nowSec, &nowNsec, (swift_clock_id)clock);
176+ SwiftTime now = swift_time_now (clock);
174177
175- uint64_t delta = (sec - nowSec ) * NSEC_PER_SEC + nsec - nowNsec ;
178+ uint64_t delta = (sec - now. seconds ) * NSEC_PER_SEC + nsec - now. nanoseconds ;
176179
177180 auto deadline = std::chrono::steady_clock::now ()
178181 + std::chrono::duration_cast<JobDeadline::duration>(
@@ -225,7 +228,7 @@ static void sleepThisThreadUntil(JobDeadline deadline) {
225228}
226229
227230// / Claim the next job from the cooperative global queue.
228- static Job *claimNextFromCooperativeGlobalQueue () {
231+ static SwiftJob *claimNextFromCooperativeGlobalQueue () {
229232 while (true ) {
230233 // Move any delayed jobs that are now ready into the primary queue.
231234 recognizeReadyDelayedJobs ();
@@ -247,22 +250,31 @@ static Job *claimNextFromCooperativeGlobalQueue() {
247250 }
248251}
249252
250- void swift::
251- swift_task_donateThreadToGlobalExecutorUntil (bool (*condition)(void *),
252- void *conditionContext) {
253+ SWIFT_CC ( swift) void
254+ swift_task_donateThreadToGlobalExecutorUntilImpl (bool (*condition)(void *),
255+ void *conditionContext) {
253256 while (!condition (conditionContext)) {
254257 auto job = claimNextFromCooperativeGlobalQueue ();
255258 if (!job) return ;
256- swift_job_run (job, SerialExecutorRef::generic ());
259+ swift_job_run (job, swift_executor_generic ());
260+ }
261+ }
262+
263+ SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_CC (swift)
264+ void swift_task_asyncMainDrainQueueImpl() {
265+ while (true ) {
266+ auto job = claimNextFromCooperativeGlobalQueue ();
267+ assert (job && " We should never run out of jobs on the async main queue." );
268+ swift_job_run (job, swift_executor_generic ());
257269 }
258270}
259271
260272SWIFT_CC (swift)
261- SerialExecutorRef swift:: swift_task_getMainExecutorImpl() {
262- return SerialExecutorRef::generic ();
273+ SwiftExecutorRef swift_task_getMainExecutorImpl() {
274+ return swift_executor_generic ();
263275}
264276
265277SWIFT_CC (swift)
266- bool swift:: swift_task_isMainExecutorImpl(SerialExecutorRef executor) {
267- return executor. isGeneric ( );
278+ bool swift_task_isMainExecutorImpl(SwiftExecutorRef executor) {
279+ return swift_executor_isGeneric (executor );
268280}
0 commit comments