@@ -164,14 +164,19 @@ class ChildTaskStatusRecord : public TaskStatusRecord {
164
164
// / and are only tracked by their respective `TaskGroupTaskStatusRecord`.
165
165
class TaskGroupTaskStatusRecord : public TaskStatusRecord {
166
166
AsyncTask *FirstChild;
167
+ AsyncTask *LastChild;
167
168
168
169
public:
169
170
TaskGroupTaskStatusRecord ()
170
- : TaskStatusRecord(TaskStatusRecordKind::TaskGroup), FirstChild(nullptr ) {
171
+ : TaskStatusRecord(TaskStatusRecordKind::TaskGroup),
172
+ FirstChild (nullptr ),
173
+ LastChild(nullptr ) {
171
174
}
172
175
173
176
TaskGroupTaskStatusRecord (AsyncTask *child)
174
- : TaskStatusRecord(TaskStatusRecordKind::TaskGroup), FirstChild(child) {}
177
+ : TaskStatusRecord(TaskStatusRecordKind::TaskGroup),
178
+ FirstChild(child),
179
+ LastChild(child) {}
175
180
176
181
TaskGroup *getGroup () { return reinterpret_cast <TaskGroup *>(this ); }
177
182
@@ -185,38 +190,28 @@ class TaskGroupTaskStatusRecord : public TaskStatusRecord {
185
190
assert (child->hasGroupChildFragment ());
186
191
assert (child->groupChildFragment ()->getGroup () == getGroup ());
187
192
193
+ auto oldLastChild = LastChild;
194
+ LastChild = child;
195
+
188
196
if (!FirstChild) {
189
197
// This is the first child we ever attach, so store it as FirstChild.
190
198
FirstChild = child;
191
199
return ;
192
200
}
193
201
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);
202
+ oldLastChild->childFragment ()->setNextChild (child);
211
203
}
212
204
213
205
void detachChild (AsyncTask *child) {
214
206
assert (child && " cannot remove a null child from group" );
215
207
if (FirstChild == child) {
216
208
FirstChild = getNextChildTask (child);
209
+ if (FirstChild == nullptr ) {
210
+ LastChild = nullptr ;
211
+ }
217
212
return ;
218
213
}
219
-
214
+
220
215
AsyncTask *prev = FirstChild;
221
216
// Remove the child from the linked list, i.e.:
222
217
// prev -> afterPrev -> afterChild
@@ -230,6 +225,9 @@ class TaskGroupTaskStatusRecord : public TaskStatusRecord {
230
225
if (afterPrev == child) {
231
226
auto afterChild = getNextChildTask (child);
232
227
prev->childFragment ()->setNextChild (afterChild);
228
+ if (child == LastChild) {
229
+ LastChild = prev;
230
+ }
233
231
return ;
234
232
}
235
233
0 commit comments