15
15
// / This file is included into GlobalExecutor.cpp only when
16
16
// / the cooperative global executor is enabled. It is expected to
17
17
// / declare the following functions:
18
+ // / swift_task_asyncMainDrainQueueImpl
19
+ // / swift_task_checkIsolatedImpl
20
+ // / swift_task_donateThreadToGlobalExecutorUntilImpl
18
21
// / swift_task_enqueueGlobalImpl
22
+ // / swift_task_enqueueGlobalWithDeadlineImpl
19
23
// / swift_task_enqueueGlobalWithDelayImpl
20
24
// / swift_task_enqueueMainExecutorImpl
21
- // / swift_task_checkIsolatedImpl
25
+ // / swift_task_getMainExecutorImpl
26
+ // / swift_task_isMainExecutorImpl
22
27
// / as well as any cooperative-executor-specific functions in the runtime.
23
28
// /
24
29
// /===------------------------------------------------------------------===///
25
30
26
- #include " swift/Runtime/Concurrency .h"
31
+ #include " swift/shims/Visibility .h"
27
32
28
33
#include < chrono>
29
34
#ifndef SWIFT_THREADING_NONE
39
44
# define NSEC_PER_SEC 1000000000ull
40
45
#endif
41
46
42
- #include " ExecutorHooks .h"
47
+ #include " ExecutorImpl .h"
43
48
44
49
using namespace swift ;
45
50
46
51
namespace {
47
52
48
53
struct 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 ]);
51
56
}
52
57
53
- static Job *getNext (Job *job) {
58
+ static SwiftJob *getNext (SwiftJob *job) {
54
59
return storage (job);
55
60
}
56
- static void setNext (Job *job, Job *next) {
61
+ static void setNext (SwiftJob *job, SwiftJob *next) {
57
62
storage (job) = next;
58
63
}
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 ));
62
67
}
63
68
};
64
- using JobPriorityQueue = PriorityQueue<Job *, JobQueueTraits>;
69
+ using JobPriorityQueue = PriorityQueue<SwiftJob *, JobQueueTraits>;
65
70
66
71
using JobDeadline = std::chrono::time_point<std::chrono::steady_clock>;
67
72
68
73
template <bool = (sizeof (JobDeadline) <= sizeof (void *) &&
69
74
alignof (JobDeadline) <= alignof (void *))>
70
75
struct JobDeadlineStorage ;
71
76
72
- // / Specialization for when JobDeadline fits in SchedulerPrivate .
77
+ // / Specialization for when JobDeadline fits in schedulerPrivate .
73
78
template <>
74
79
struct 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 ]);
77
82
}
78
- static JobDeadline get (Job *job) {
83
+ static JobDeadline get (SwiftJob *job) {
79
84
return storage (job);
80
85
}
81
- static void set (Job *job, JobDeadline deadline) {
86
+ static void set (SwiftJob *job, JobDeadline deadline) {
82
87
new (static_cast <void *>(&storage (job))) JobDeadline (deadline);
83
88
}
84
- static void destroy (Job *job) {
89
+ static void destroy (SwiftJob *job) {
85
90
storage (job).~JobDeadline ();
86
91
}
87
92
};
88
93
89
- // / Specialization for when JobDeadline doesn't fit in SchedulerPrivate .
94
+ // / Specialization for when JobDeadline doesn't fit in schedulerPrivate .
90
95
template <>
91
96
struct 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 ]);
94
99
}
95
- static JobDeadline get (Job *job) {
100
+ static JobDeadline get (SwiftJob *job) {
96
101
return *storage (job);
97
102
}
98
- static void set (Job *job, JobDeadline deadline) {
103
+ static void set (SwiftJob *job, JobDeadline deadline) {
99
104
storage (job) = new JobDeadline (deadline);
100
105
}
101
- static void destroy (Job *job) {
106
+ static void destroy (SwiftJob *job) {
102
107
delete storage (job);
103
108
}
104
109
};
105
110
106
111
} // end anonymous namespace
107
112
108
113
static JobPriorityQueue JobQueue;
109
- static Job *DelayedJobQueue = nullptr ;
114
+ static SwiftJob *DelayedJobQueue = nullptr ;
110
115
111
116
// / Insert a job into the cooperative global queue.
112
117
SWIFT_CC (swift)
113
- void swift:: swift_task_enqueueGlobalImpl(Job *job) {
118
+ void swift_task_enqueueGlobalImpl(SwiftJob *job) {
114
119
assert (job && " no job provided" );
115
120
JobQueue.enqueue (job);
116
121
}
117
122
118
123
// / Enqueues a task on the main executor.
119
124
SWIFT_CC (swift)
120
- void swift:: swift_task_enqueueMainExecutorImpl(Job *job) {
125
+ void swift_task_enqueueMainExecutorImpl(SwiftJob *job) {
121
126
// The cooperative executor does not distinguish between the main
122
127
// queue and the global queue.
123
128
swift_task_enqueueGlobalImpl (job);
124
129
}
125
130
126
- static void insertDelayedJob (Job *newJob, JobDeadline deadline) {
127
- Job **position = &DelayedJobQueue;
131
+ static void insertDelayedJob (SwiftJob *newJob, JobDeadline deadline) {
132
+ SwiftJob **position = &DelayedJobQueue;
128
133
while (auto cur = *position) {
129
134
// If we find a job with a later deadline, insert here.
130
135
// Note that we maintain FIFO order.
@@ -142,14 +147,14 @@ static void insertDelayedJob(Job *newJob, JobDeadline deadline) {
142
147
}
143
148
144
149
SWIFT_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);
147
152
}
148
153
149
154
// / Insert a job into the cooperative global queue with a delay.
150
155
SWIFT_CC (swift)
151
- void swift:: swift_task_enqueueGlobalWithDelayImpl(JobDelay delay,
152
- Job *newJob) {
156
+ void swift_task_enqueueGlobalWithDelayImpl(SwiftJobDelay delay,
157
+ SwiftJob *newJob) {
153
158
assert (newJob && " no job provided" );
154
159
155
160
auto deadline = std::chrono::steady_clock::now ()
@@ -161,18 +166,16 @@ void swift::swift_task_enqueueGlobalWithDelayImpl(JobDelay delay,
161
166
}
162
167
163
168
SWIFT_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) {
169
174
assert (newJob && " no job provided" );
170
175
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);
174
177
175
- uint64_t delta = (sec - nowSec ) * NSEC_PER_SEC + nsec - nowNsec ;
178
+ uint64_t delta = (sec - now. seconds ) * NSEC_PER_SEC + nsec - now. nanoseconds ;
176
179
177
180
auto deadline = std::chrono::steady_clock::now ()
178
181
+ std::chrono::duration_cast<JobDeadline::duration>(
@@ -225,7 +228,7 @@ static void sleepThisThreadUntil(JobDeadline deadline) {
225
228
}
226
229
227
230
// / Claim the next job from the cooperative global queue.
228
- static Job *claimNextFromCooperativeGlobalQueue () {
231
+ static SwiftJob *claimNextFromCooperativeGlobalQueue () {
229
232
while (true ) {
230
233
// Move any delayed jobs that are now ready into the primary queue.
231
234
recognizeReadyDelayedJobs ();
@@ -247,22 +250,31 @@ static Job *claimNextFromCooperativeGlobalQueue() {
247
250
}
248
251
}
249
252
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) {
253
256
while (!condition (conditionContext)) {
254
257
auto job = claimNextFromCooperativeGlobalQueue ();
255
258
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 ());
257
269
}
258
270
}
259
271
260
272
SWIFT_CC (swift)
261
- SerialExecutorRef swift:: swift_task_getMainExecutorImpl() {
262
- return SerialExecutorRef::generic ();
273
+ SwiftExecutorRef swift_task_getMainExecutorImpl() {
274
+ return swift_executor_generic ();
263
275
}
264
276
265
277
SWIFT_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 );
268
280
}
0 commit comments