@@ -164,14 +164,21 @@ class ChildTaskStatusRecord : public TaskStatusRecord {
164164// / and are only tracked by their respective `TaskGroupTaskStatusRecord`.
165165class TaskGroupTaskStatusRecord : public TaskStatusRecord {
166166 AsyncTask *FirstChild;
167+ AsyncTask *LastChild;
167168
168169public:
169170 TaskGroupTaskStatusRecord ()
170- : TaskStatusRecord(TaskStatusRecordKind::TaskGroup), FirstChild(nullptr ) {
171+ : TaskStatusRecord(TaskStatusRecordKind::TaskGroup),
172+ FirstChild (nullptr ),
173+ LastChild(nullptr ) {
171174 }
172175
173176 TaskGroupTaskStatusRecord (AsyncTask *child)
174- : TaskStatusRecord(TaskStatusRecordKind::TaskGroup), FirstChild(child) {}
177+ : TaskStatusRecord(TaskStatusRecordKind::TaskGroup),
178+ FirstChild(child),
179+ LastChild(child) {
180+ assert (!LastChild || !LastChild->childFragment ()->getNextChild ());
181+ }
175182
176183 TaskGroup *getGroup () { return reinterpret_cast <TaskGroup *>(this ); }
177184
@@ -185,38 +192,28 @@ class TaskGroupTaskStatusRecord : public TaskStatusRecord {
185192 assert (child->hasGroupChildFragment ());
186193 assert (child->groupChildFragment ()->getGroup () == getGroup ());
187194
195+ auto oldLastChild = LastChild;
196+ LastChild = child;
197+
188198 if (!FirstChild) {
189199 // This is the first child we ever attach, so store it as FirstChild.
190200 FirstChild = child;
191201 return ;
192202 }
193203
194- // We need to traverse the siblings to find the last one and add the child
195- // there.
196- // FIXME: just set prepend to the current head, no need to traverse.
197-
198- auto cur = FirstChild;
199- while (cur) {
200- // no need to check hasChildFragment, all tasks we store here have them.
201- auto fragment = cur->childFragment ();
202- if (auto next = fragment->getNextChild ()) {
203- cur = next;
204- } else {
205- // we're done searching and `cur` is the last
206- break ;
207- }
208- }
209-
210- cur->childFragment ()->setNextChild (child);
204+ oldLastChild->childFragment ()->setNextChild (child);
211205 }
212206
213207 void detachChild (AsyncTask *child) {
214208 assert (child && " cannot remove a null child from group" );
215209 if (FirstChild == child) {
216210 FirstChild = getNextChildTask (child);
211+ if (FirstChild == nullptr ) {
212+ LastChild = nullptr ;
213+ }
217214 return ;
218215 }
219-
216+
220217 AsyncTask *prev = FirstChild;
221218 // Remove the child from the linked list, i.e.:
222219 // prev -> afterPrev -> afterChild
@@ -230,6 +227,9 @@ class TaskGroupTaskStatusRecord : public TaskStatusRecord {
230227 if (afterPrev == child) {
231228 auto afterChild = getNextChildTask (child);
232229 prev->childFragment ()->setNextChild (afterChild);
230+ if (child == LastChild) {
231+ LastChild = prev;
232+ }
233233 return ;
234234 }
235235
0 commit comments