Skip to content

Commit 83e3ae8

Browse files
authored
Merge pull request #40265 from mikeash/task-id-64-bit
2 parents 7150a8b + bac6965 commit 83e3ae8

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

include/swift/ABI/Task.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ class AsyncTask : public Job {
250250
: Job(flags, run, metadata, captureCurrentVoucher),
251251
ResumeContext(initialContext) {
252252
assert(flags.isAsyncTask());
253-
Id = getNextTaskId();
253+
setTaskId();
254254
}
255255

256256
/// Create a task with "immortal" reference counts.
@@ -265,11 +265,14 @@ class AsyncTask : public Job {
265265
: Job(flags, run, metadata, immortal, captureCurrentVoucher),
266266
ResumeContext(initialContext) {
267267
assert(flags.isAsyncTask());
268-
Id = getNextTaskId();
268+
setTaskId();
269269
}
270270

271271
~AsyncTask();
272272

273+
/// Set the task's ID field to the next task ID.
274+
void setTaskId();
275+
273276
/// Given that we've already fully established the job context
274277
/// in the current thread, start running this task. To establish
275278
/// the job context correctly, call swift_job_run or
@@ -566,14 +569,6 @@ class AsyncTask : public Job {
566569
return reinterpret_cast<AsyncTask *&>(
567570
SchedulerPrivate[NextWaitingTaskIndex]);
568571
}
569-
570-
/// Get the next non-zero Task ID.
571-
uint32_t getNextTaskId() {
572-
static std::atomic<uint32_t> Id(1);
573-
uint32_t Next = Id.fetch_add(1, std::memory_order_relaxed);
574-
if (Next == 0) Next = Id.fetch_add(1, std::memory_order_relaxed);
575-
return Next;
576-
}
577572
};
578573

579574
// The compiler will eventually assume these.

stdlib/public/Concurrency/Task.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,19 @@ AsyncTask::~AsyncTask() {
247247
Private.destroy();
248248
}
249249

250+
void AsyncTask::setTaskId() {
251+
static std::atomic<uint64_t> NextId(1);
252+
253+
// We want the 32-bit Job::Id to be non-zero, so loop if we happen upon zero.
254+
uint64_t Fetched;
255+
do {
256+
Fetched = NextId.fetch_add(1, std::memory_order_relaxed);
257+
Id = Fetched & 0xffffffff;
258+
} while (Id == 0);
259+
260+
_private().Id = (Fetched >> 32) & 0xffffffff;
261+
}
262+
250263
SWIFT_CC(swift)
251264
static void destroyTask(SWIFT_CONTEXT HeapObject *obj) {
252265
auto task = static_cast<AsyncTask*>(obj);

stdlib/public/Concurrency/TaskPrivate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,9 @@ struct AsyncTask::PrivateStorage {
295295
/// state.
296296
uintptr_t ExclusivityAccessSet[2] = {0, 0};
297297

298+
/// The top 32 bits of the task ID. The bottom 32 bits are in Job::Id.
299+
uint32_t Id;
300+
298301
PrivateStorage(JobFlags flags)
299302
: Status(ActiveTaskStatus(flags)), Local(TaskLocal::Storage()) {}
300303

0 commit comments

Comments
 (0)