Example #1
0
//--------------------------------------------------------------------------------------
// FUNCTION: RCCE_barrier
//--------------------------------------------------------------------------------------
// very simple, linear barrier 
//--------------------------------------------------------------------------------------
int RCCE_barrier(RCCE_COMM *comm) {
 
  int               counter, i, error;
  int               ROOT =  0;
  t_vchar           cyclechar[RCCE_LINE_SIZE];
  t_vchar           valchar  [RCCE_LINE_SIZE];
  t_vcharp gatherp, releasep;
  RCCE_FLAG_STATUS  cycle;

  counter = 0;

  gatherp = comm->gather.line_address;

  if (RCCE_debug_synch) 
    fprintf(STDERR,"UE %d has checked into barrier\n", RCCE_IAM);
  // flip local barrier variable                                      
  if (error = RCCE_get(cyclechar, gatherp, RCCE_LINE_SIZE, RCCE_IAM))
    return(RCCE_error_return(RCCE_debug_synch,error));
  cycle = RCCE_flip_bit_value(cyclechar, comm->gather.location);
  if (error = RCCE_put(comm->gather.line_address, cyclechar, RCCE_LINE_SIZE, RCCE_IAM))
    return(RCCE_error_return(RCCE_debug_synch,error));

  if (RCCE_IAM==comm->member[ROOT]) {
    // read "remote" gather flags; once all equal "cycle" (i.e counter==comm->size), 
    // we know all UEs have reached the barrier                   
    while (counter != comm->size) {
      // skip the first member (#0), because that is the ROOT         
      for (counter=i=1; i<comm->size; i++) {
        // copy flag values out of comm buffer                        
        if (error = RCCE_get(valchar, comm->gather.line_address, RCCE_LINE_SIZE, 
                             comm->member[i]))
          return(RCCE_error_return(RCCE_debug_synch,error));
        if (RCCE_bit_value(valchar, comm->gather.location) == cycle) counter++;
      }
    }
    // set release flags                                              
    for (i=1; i<comm->size; i++) 
      if (error = RCCE_flag_write(&(comm->release), cycle, comm->member[i]))
        return(RCCE_error_return(RCCE_debug_synch,error));
  }
  else {
    if (error = RCCE_wait_until(comm->release, cycle))
      return(RCCE_error_return(RCCE_debug_synch,error));
  }
  if (RCCE_debug_synch) fprintf(STDERR,"UE %d has cleared barrier\n", RCCE_IAM);  
  return(RCCE_SUCCESS);
}
Example #2
0
//--------------------------------------------------------------------------------------
// FUNCTION: RCCE_flag_free
//--------------------------------------------------------------------------------------
// free space for one flag. Since multiple fit on a single cache line, we only
// need to free claimed MPB space when the all existing lines are completely emptied.
//--------------------------------------------------------------------------------------
int    RCCE_flag_free(RCCE_FLAG *flag) {

  RCCE_FLAG_LINE *flagp, *flagpminus1 = NULL;
  int loc;

  // check wether flag exists, and whether the location field is valid 
  if (!flag || flag->location < 0) 
    return(RCCE_error_return(RCCE_debug_synch,RCCE_ERROR_FLAG_UNDEFINED));
  // find flag line in globally maintained structure                   
  flagp  = &RCCE_flags;
  while (flagp->next && flag->line_address != flagp->line_address) {
    flagpminus1 = flagp;
    flagp = flagp->next;
  }
  if (flag->line_address != flagp->line_address) 
    return(RCCE_error_return(RCCE_debug_synch,RCCE_ERROR_FLAG_UNDEFINED));

  // error checking is done
  flagp->members--; 
  loc = flag->location;
#ifdef SINGLEBITFLAGS
  RCCE_flip_bit_value(flagp->flag+loc/RCCE_FLAGS_PER_BYTE,loc%RCCE_FLAGS_PER_BYTE);
#else
  flagp->flag[flag->location] = (char) ((unsigned int) 0);
#endif
  // something special happens if we've emptied an entire line         
  if (flagp->members==0) {
    if (flagpminus1) {
      // there is a predecessor; splice out current flag line from linked list
      RCCE_free(flagp->line_address);
      flagpminus1->next = flagp->next;
      free(flagp); 
    } 
    // if there is a successor but no predecessor, do nothing          
  }
  // invalidate location field to make sure we won't free again by mistake
  flag->location = -1;
  flag->line_address = NULL;

  return(RCCE_SUCCESS);
}