From e54b0e132b0f1ec6529812f6852b8b61422cd88d Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Fri, 21 Oct 2011 14:21:39 -0700 Subject: [PATCH] add test and set barrier --- arch/x86/include/asm/RCCE.h | 1 + arch/x86/scc/RCCE_admin.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/arch/x86/include/asm/RCCE.h b/arch/x86/include/asm/RCCE.h index 128ba664..d88e5723 100644 --- a/arch/x86/include/asm/RCCE.h +++ b/arch/x86/include/asm/RCCE.h @@ -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); diff --git a/arch/x86/scc/RCCE_admin.c b/arch/x86/scc/RCCE_admin.c index 78b26b21..09e70166 100644 --- a/arch/x86/scc/RCCE_admin.c +++ b/arch/x86/scc/RCCE_admin.c @@ -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 //--------------------------------------------------------------------------------------