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