@@ -385,35 +385,30 @@ static Closure *Closure_return(__cilkrts_worker *const w, worker_id self,
385385 child->lock (self);
386386
387387 // 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+ // The following code used to be in a loop. Now this function
389+ // is called multiple times if necessary to finish reduction.
390+
391+ // invariant: a closure cannot unlink itself w/out lock on parent
392+ // so what this points to cannot change while we have lock on parent
416393
394+ hyper_table *rht = child->right_ht ;
395+ child->right_ht = nullptr ;
396+
397+ // Get the "left" hypermap, which either belongs to a left sibling, if
398+ // it exists, or the parent, otherwise.
399+ hyper_table **lht_ptr;
400+ Closure *const left_sib = child->left_sib ;
401+ if (left_sib != nullptr ) {
402+ lht_ptr = &left_sib->right_ht ;
403+ } else {
404+ lht_ptr = &parent->child_ht ;
405+ }
406+ hyper_table *lht = *lht_ptr;
407+ *lht_ptr = nullptr ;
408+
409+ // If we have no hypermaps on either the left or right, deposit the
410+ // active hypermap and break from the loop.
411+ if (lht != nullptr || rht != nullptr ) {
417412 child->set_status (CLOSURE_RUNNING);
418413
419414 child->unlock (self);
@@ -430,6 +425,11 @@ static Closure *Closure_return(__cilkrts_worker *const w, worker_id self,
430425 return child;
431426 }
432427
428+ // Deposit the current active hypermap
429+ hyper_table *active_ht = w->hyper_table ;
430+ w->hyper_table = nullptr ;
431+ *lht_ptr = active_ht;
432+
433433 // Cilk_exception_handler ended up pushing a stack frame onto child, to do
434434 // reductions. Because there are no reductions to do, pop that frame.
435435 __cilkrts_leave_frame (child->frame );
0 commit comments