1
/* $Id: nxtval.shm.c,v 1.9 2005-02-21 21:51:40 manoj Exp $ */
5
long *nxtval_shmem = &nxtval_counter;
8
#include "tcgmsg_vampir.h"
12
#define INCR 1 /* increment for NXTVAL */
13
#define BUSY -1L /* indicates somebody else updating counter*/
16
#if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__)
17
# define TESTANDSET testandset
19
static inline int testandset(int *spinlock)
22
__asm__ __volatile__("xchgl %0, %1"
23
: "=r"(ret), "=m"(*spinlock)
24
: "0"(1), "m"(*spinlock));
29
#elif defined(MACX) && defined(__GNUC__)
30
# define TESTANDSET(x) ( krspin_lock((long int *)(x)))
31
static int krspin_lock(long int *p)
55
# define LOCK if(nproc>1)acquire_spinlock((int*)(nxtval_shmem+1))
56
# define UNLOCK if(nproc>1)release_spinlock((int*)(nxtval_shmem+1))
58
static void acquire_spinlock(int *mutex)
60
int loop=0, maxloop =10;
61
while (TESTANDSET(mutex)){
63
if(loop==maxloop){ usleep(1); loop=0; }
67
static void release_spinlock(int *mutex)
75
# define LOCK if(nproc>1)Error("nxtval: sequential version with silly mproc ", (Integer) *mproc);
80
long NXTVAL_(long *mproc)
82
Get next value of shared counter.
84
mproc > 0 ... returns requested value
85
mproc < 0 ... server blocks until abs(mproc) processes are queued
87
mproc = 0 ... indicates to server that I am about to terminate
93
long sync_type= INTERNAL_SYNC_TYPE;
94
long nproc= NNODES_();
99
vampir_begin(TCGMSG_NXTVAL,__FILE__,__LINE__);
103
(void) printf("%2ld: nxtval: mproc=%ld\n",NODEID_(), *mproc);
104
(void) fflush(stdout);
109
/* reset the counter value to zero */
110
if( NODEID_() == server) *nxtval_shmem = 0;
115
vampir_start_comm(server,me,sizeof(long),TCGMSG_NXTVAL);
119
local = *nxtval_shmem;
120
*nxtval_shmem += INCR;
124
vampir_end_comm(server,me,sizeof(long),TCGMSG_NXTVAL);
129
vampir_end(TCGMSG_NXTVAL,__FILE__,__LINE__);