@@ -377,43 +377,35 @@ static Closure *Closure_return(__cilkrts_worker *const w, worker_id self,
377377 /* If in the future the worker's map is not created lazily,
378378 assert it is not null here. */
379379
380- /* need a loop as multiple siblings can return while we
381- are performing reductions */
380+ // Multiple siblings can return while we are performing reductions.
381+ // The following code used to be in a loop. Now this function
382+ // is called multiple times if necessary to finish reduction.
382383
383384 // always lock from top to bottom
384385 parent->lock (self);
385386 child->lock (self);
386387
387- // Deal with reducers.
388- while (true ) {
389- // invariant: a closure cannot unlink itself w/out lock on parent
390- // so what this points to cannot change while we have lock on parent
391-
392- hyper_table *rht = child->right_ht ;
393- child->right_ht = nullptr ;
394-
395- // Get the "left" hypermap, which either belongs to a left sibling, if
396- // it exists, or the parent, otherwise.
397- hyper_table **lht_ptr;
398- Closure *const left_sib = child->left_sib ;
399- if (left_sib != nullptr ) {
400- lht_ptr = &left_sib->right_ht ;
401- } else {
402- lht_ptr = &parent->child_ht ;
403- }
404- hyper_table *lht = *lht_ptr;
405- *lht_ptr = nullptr ;
406-
407- // If we have no hypermaps on either the left or right, deposit the
408- // active hypermap and break from the loop.
409- if (lht == nullptr && rht == nullptr ) {
410- // Deposit the current active hypermap
411- hyper_table *active_ht = w->hyper_table ;
412- w->hyper_table = nullptr ;
413- *lht_ptr = active_ht;
414- break ;
415- }
388+ // invariant: a closure cannot unlink itself w/out lock on parent
389+ // so what this points to cannot change while we have lock on parent
416390
391+ hyper_table *rht = child->right_ht ;
392+ child->right_ht = nullptr ;
393+
394+ // Get the "left" hypermap, which either belongs to a left sibling, if
395+ // it exists, or the parent, otherwise.
396+ hyper_table **lht_ptr;
397+ Closure *const left_sib = child->left_sib ;
398+ if (left_sib != nullptr ) {
399+ lht_ptr = &left_sib->right_ht ;
400+ } else {
401+ lht_ptr = &parent->child_ht ;
402+ }
403+ hyper_table *lht = *lht_ptr;
404+ *lht_ptr = nullptr ;
405+
406+ // If we have hypermaps on either the left or right, arrange
407+ // for them to be merged.
408+ if (lht != nullptr || rht != nullptr ) {
417409 child->set_status (CLOSURE_RUNNING);
418410
419411 child->unlock (self);
@@ -430,6 +422,11 @@ static Closure *Closure_return(__cilkrts_worker *const w, worker_id self,
430422 return child;
431423 }
432424
425+ // Deposit the current active hypermap
426+ hyper_table *active_ht = w->hyper_table ;
427+ w->hyper_table = nullptr ;
428+ *lht_ptr = active_ht;
429+
433430 // Cilk_exception_handler ended up pushing a stack frame onto child, to do
434431 // reductions. Because there are no reductions to do, pop that frame.
435432 __cilkrts_leave_frame (child->frame );
0 commit comments