add test and set barrier

This commit is contained in:
Stefan Lankes 2011-10-21 14:21:39 -07:00
parent 1f7f702ae3
commit e54b0e132b
2 changed files with 35 additions and 0 deletions

View file

@ -190,6 +190,7 @@ int RCCE_comm_size(RCCE_COMM, int *);
int RCCE_comm_rank(RCCE_COMM, int *);
void RCCE_fence(void);
int RCCE_barrier(RCCE_COMM *);
int RCCE_TNS_barrier(RCCE_COMM* comm);
int RCCE_error_string(int, char *, int *);
int RCCE_debug_set(int);
int RCCE_debug_unset(int);

View file

@ -48,6 +48,8 @@
// En-/ or disable debug prints...
#define DEBUG 0
#define Test_and_Set(a) ((*(virtual_lockaddress[a])) & 0x01)
//......................................................................................
// GLOBAL VARIABLES USED BY THE LIBRARY
//......................................................................................
@ -105,6 +107,38 @@ void RC_cache_invalidate() {
return;
}
int RCCE_TNS_barrier(RCCE_COMM* comm) {
// two roundtrips to realize a barrier using a T&S Register for each core.
// 1. search first free T&S Register to spin
// 2. last waiter wakes up first waiter and continues local wait
// 3. first waiter wakes up second waiter by releasing its lock ...
// At least every used T&S Register is 0 and no UE can overtake a barrier.
int num = comm->size;
int step = 0;
//fprintf(stderr,"%d:\t enter barrier \n",id);
while( !Test_and_Set(step) ) ++step;
// only one UE runs until T&S # num-1
//fprintf(stderr,"%d:\t step %d\n",id,step);
if(step == num-1) {
//fprintf(stderr,"%d:\t I am the last one\n",id);
*(virtual_lockaddress[0]) = 0x0;
while(!Test_and_Set(step)) ;
*(virtual_lockaddress[step]) = 0x0;
} else {
while(!Test_and_Set(step)) ;
*(virtual_lockaddress[step]) = 0x0;
*(virtual_lockaddress[step+1]) = 0x0;
}
//fprintf(stderr,"released barrier! step: %d\n", step);
return RCCE_SUCCESS;
}
//--------------------------------------------------------------------------------------
// FUNCTION: RC_COMM_BUFFER_SIZE
//--------------------------------------------------------------------------------------