Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions include/swift/ABI/TaskStatus.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,21 @@ class ChildTaskStatusRecord : public TaskStatusRecord {
/// and are only tracked by their respective `TaskGroupTaskStatusRecord`.
class TaskGroupTaskStatusRecord : public TaskStatusRecord {
AsyncTask *FirstChild;
AsyncTask *LastChild;

public:
TaskGroupTaskStatusRecord()
: TaskStatusRecord(TaskStatusRecordKind::TaskGroup), FirstChild(nullptr) {
: TaskStatusRecord(TaskStatusRecordKind::TaskGroup),
FirstChild(nullptr),
LastChild(nullptr) {
}

TaskGroupTaskStatusRecord(AsyncTask *child)
: TaskStatusRecord(TaskStatusRecordKind::TaskGroup), FirstChild(child) {}
: TaskStatusRecord(TaskStatusRecordKind::TaskGroup),
FirstChild(child),
LastChild(child) {
assert(!LastChild || !LastChild->childFragment()->getNextChild());
}

TaskGroup *getGroup() { return reinterpret_cast<TaskGroup *>(this); }

Expand All @@ -185,38 +192,28 @@ class TaskGroupTaskStatusRecord : public TaskStatusRecord {
assert(child->hasGroupChildFragment());
assert(child->groupChildFragment()->getGroup() == getGroup());

auto oldLastChild = LastChild;
LastChild = child;

if (!FirstChild) {
// This is the first child we ever attach, so store it as FirstChild.
FirstChild = child;
return;
}

// We need to traverse the siblings to find the last one and add the child
// there.
// FIXME: just set prepend to the current head, no need to traverse.

auto cur = FirstChild;
while (cur) {
// no need to check hasChildFragment, all tasks we store here have them.
auto fragment = cur->childFragment();
if (auto next = fragment->getNextChild()) {
cur = next;
} else {
// we're done searching and `cur` is the last
break;
}
}

cur->childFragment()->setNextChild(child);
oldLastChild->childFragment()->setNextChild(child);
}

void detachChild(AsyncTask *child) {
assert(child && "cannot remove a null child from group");
if (FirstChild == child) {
FirstChild = getNextChildTask(child);
if (FirstChild == nullptr) {
LastChild = nullptr;
}
return;
}

AsyncTask *prev = FirstChild;
// Remove the child from the linked list, i.e.:
// prev -> afterPrev -> afterChild
Expand All @@ -230,6 +227,9 @@ class TaskGroupTaskStatusRecord : public TaskStatusRecord {
if (afterPrev == child) {
auto afterChild = getNextChildTask(child);
prev->childFragment()->setNextChild(afterChild);
if (child == LastChild) {
LastChild = prev;
}
return;
}

Expand Down