lib/libopenpop/hierarchy.c
void hierarchy_hybrid_barrier_final(int nid, const char *desc)
{
  bool leader;
  unsigned awaited_final;
#ifdef _TIME_BARRIER
  struct timespec start, end;
#endif

  leader = hierarchy_select_leader_synchronous(&popcorn_node[nid].sync, NULL);
  if(leader)
  {
#ifdef _TIME_BARRIER
    clock_gettime(CLOCK_MONOTONIC, &start);
#endif
    // Wait for non-leader threads to enter per-node barrier
    do awaited_final = __atomic_load_n(&popcorn_node[nid].bar.awaited_final,
                                       MEMMODEL_ACQUIRE);
    while(awaited_final != 1);
    gomp_team_barrier_wait_final_nospin(&popcorn_global.bar);
#ifdef _TIME_BARRIER
    clock_gettime(CLOCK_MONOTONIC, &end);
    printf("%s final team barrier wait: %lld ns\n",
           (desc ? desc : "Anonymous"),
           ELAPSED(start, end));
#endif
    gomp_team_barrier_wait_final_last(&popcorn_node[nid].bar);
  }
  else gomp_team_barrier_wait_final(&popcorn_node[nid].bar);
}
/* End-of-parallel section barriers are a little tricky because upon starting
   the next section the main thread will reset the per-node synchronization
   data.  We need to ensure that all non-leader threads reach the per-node
   barrier *before* performing global synchronization.  Once this is
   accomplished the leader can unconditionally release the threads waiting at
   the per-node barrier.  Note that this function *requires* the main thread
   to call hierarchy_init_node() upon starting the next section, as we leave
   the per-node barrier in an inconsistent state to avoid race conditions. */
End-of-parallel section barriers are a little tricky because upon starting
the next section the main thread will reset the per-node synchronization
data.  We need to ensure that all non-leader threads reach the per-node
barrier *before* performing global synchronization.  Once this is
accomplished the leader can unconditionally release the threads waiting at
the per-node barrier.  Note that this function *requires* the main thread
to call hierarchy_init_node() upon starting the next section, as we leave
the per-node barrier in an inconsistent state to avoid race conditions.
End - of - parallel section barriers are a little tricky because upon starting the next section the main thread will reset the per - node synchronization data . We need to ensure that all non - leader threads reach the per - node barrier * before * performing global synchronization . Once this is accomplished the leader can unconditionally release the threads waiting at the per - node barrier . Note that this function * requires * the main thread to call hierarchy_init_node () upon starting the next section as we leave the per - node barrier in an inconsistent state to avoid race conditions .
void hierarchy_hybrid_barrier_final(int nid, const char *desc)
{
  bool leader;
  unsigned awaited_final;
#ifdef _TIME_BARRIER
  struct timespec start, end;
#endif
  leader = hierarchy_select_leader_synchronous(&popcorn_node[nid].sync, NULL);
  if(leader)
  {
#ifdef _TIME_BARRIER
    clock_gettime(CLOCK_MONOTONIC, &start);
#endif
    do awaited_final = __atomic_load_n(&popcorn_node[nid].bar.awaited_final,
                                       MEMMODEL_ACQUIRE);
    while(awaited_final != 1);
    gomp_team_barrier_wait_final_nospin(&popcorn_global.bar);
#ifdef _TIME_BARRIER
    clock_gettime(CLOCK_MONOTONIC, &end);
    printf("%s final team barrier wait: %lld ns\n",
           (desc ? desc : "Anonymous"),
           ELAPSED(start, end));
#endif
    gomp_team_barrier_wait_final_last(&popcorn_node[nid].bar);
  }
  else gomp_team_barrier_wait_final(&popcorn_node[nid].bar);
}
void hierarchy_hybrid_barrier_final ( int nid , const char * desc ) { bool leader ; unsigned awaited_final ; #ifdef _TIME_BARRIER struct timespec start , end ; #endif leader = hierarchy_select_leader_synchronous ( & popcorn_node [ nid ] . sync , NULL ) ; if ( leader ) { #ifdef _TIME_BARRIER clock_gettime ( CLOCK_MONOTONIC , & start ) ; #endif do awaited_final = __atomic_load_n ( & popcorn_node [ nid ] . bar . awaited_final , MEMMODEL_ACQUIRE ) ; while ( awaited_final != 1 ) ; gomp_team_barrier_wait_final_nospin ( & popcorn_global . bar ) ; #ifdef _TIME_BARRIER clock_gettime ( CLOCK_MONOTONIC , & end ) ; printf ( " \n " , ( desc ? desc : " " ) , ELAPSED ( start , end ) ) ; #endif gomp_team_barrier_wait_final_last ( & popcorn_node [ nid ] . bar ) ; } else gomp_team_barrier_wait_final ( & popcorn_node [ nid ] . bar ) ; }
End-of-parallel section barriers are a little tricky because upon starting
the next section the main thread will reset the per-node synchronization
data.
End - of - parallel section barriers are a little tricky because upon starting the next section the main thread will reset the per - node synchronization data .
// Wait for non-leader threads to enter per-node barrier