1 #if HAVE_CONFIG_H
2 #   include "config.h"
3 #endif
4 
5 /* $Id: locks.c,v 1.15.6.1 2006-12-14 13:24:36 manoj Exp $ */
6 #define _LOCKS_C_
7 #include "armcip.h"
8 #include "locks.h"
9 #if HAVE_UNISTD_H
10 #   include <unistd.h>
11 #endif
12 #if HAVE_STDIO_H
13 #   include <stdio.h>
14 #endif
15 
16 PAD_LOCK_T *_armci_int_mutexes;
17 
18 #if !defined(armci_die)
19 extern void armci_die(char*,int);
20 #endif
21 
22 #if defined(SPINLOCK) || defined(PMUTEX) || defined(PSPIN)
23 
24 void **ptr_arr;
25 
26 #ifdef SGIALTIX
27 
CreateInitLocks(int num_locks,lockset_t * plockid)28 void CreateInitLocks(int num_locks, lockset_t *plockid)
29 {
30 int locks_per_proc, size;
31 
32     /* locks per process in the SMP node */
33     locks_per_proc = num_locks/armci_clus_info[armci_clus_me].nslave + 1;
34     locks_per_proc = num_locks; /* this is am altix hack and no clue why this is works */
35     size=locks_per_proc*sizeof(PAD_LOCK_T);
36     ptr_arr = (void**)malloc(armci_nproc*sizeof(void*));
37     PARMCI_Malloc(ptr_arr, size);
38     _armci_int_mutexes = (PAD_LOCK_T*) ptr_arr;
39     bzero((char*)ptr_arr[armci_me],size);
40 }
41 
DeleteLocks(lockset_t lockid)42 void DeleteLocks(lockset_t lockid) {
43     ptr_arr = (void**)_armci_int_mutexes;
44     PARMCI_Free(ptr_arr[armci_me]);
45     _armci_int_mutexes = (PAD_LOCK_T*)0;
46 }
47 
48 #else
49 
CreateInitLocks(int num_locks,lockset_t * plockid)50 void CreateInitLocks(int num_locks, lockset_t *plockid)
51 {
52 int locks_per_proc, size;
53 #ifdef BGML
54   fprintf(stderr,"createinitlocks\n");
55 #endif
56   ptr_arr = (void**)malloc(armci_nproc*sizeof(void*));
57   locks_per_proc = (num_locks*armci_nclus)/armci_nproc + 1;
58   size=locks_per_proc*sizeof(PAD_LOCK_T);
59   PARMCI_Malloc(ptr_arr, size);
60   _armci_int_mutexes = (PAD_LOCK_T*) ptr_arr[armci_master];
61 
62   if(!_armci_int_mutexes) armci_die("Failed to create spinlocks",size);
63 
64 #ifdef PMUTEX
65   if(armci_me == armci_master) {
66        int i;
67        pthread_mutexattr_t pshared;
68        if(pthread_mutexattr_init(&pshared))
69             armci_die("armci_allocate_locks: could not init mutex attr",0);
70 #      ifndef LINUX
71          if(pthread_mutexattr_setpshared(&pshared,PTHREAD_PROCESS_SHARED))
72             armci_die("armci_allocate_locks: could not set PROCESS_SHARED",0);
73 #      endif
74 
75        for(i=0; i< locks_per_proc*armci_clus_info[armci_clus_me].nslave; i++){
76              if(pthread_mutex_init(_armci_int_mutexes+i,&pshared))
77                 armci_die("armci_allocate_locks: could not init mutex",i);
78        }
79   }
80 #elif defined(PSPIN)
81   if(armci_me == armci_master) {
82        for(i=0; i< locks_per_proc*armci_clus_info[armci_clus_me].nslave; i++){
83              if(pthread_spin_init(_armci_int_mutexes+i,PTHREAD_PROCESS_SHARED))
84                 armci_die("armci_allocate_locks: could not init mutex",i);
85        }
86   }
87 #else
88   bzero((char*)ptr_arr[armci_me],size);
89 #endif
90 }
91 
InitLocks(int num_locks,lockset_t lockid)92 void InitLocks(int num_locks, lockset_t lockid)
93 {
94     /* what are you doing here ?
95        All processes should've called CreateInitLocks().
96        Check preprocessor directtives and see lock allocation in armci_init */
97     armci_die("InitLocks(): what are you doing here ?",armci_me);
98 }
99 
100 
DeleteLocks(lockset_t lockid)101 void DeleteLocks(lockset_t lockid)
102 {
103   _armci_int_mutexes = (PAD_LOCK_T*)0;
104 }
105 #endif
106 
107 
108 /********************* all SGI systems ****************/
109 #elif defined(SGI)
110 #define FILE_LEN 200
111 lockset_t lockset;
112 static char arena_name[FILE_LEN];
113 usptr_t *arena_ptr;
114 static int avail =0;
115 
116 extern char *getenv(const char *);
117 
CreateInitLocks(int num_locks,lockset_t * lockid)118 void CreateInitLocks(int num_locks, lockset_t *lockid)
119 {
120 int i;
121 char *tmp;
122 
123    if(num_locks > NUM_LOCKS) armci_die("To many locks requested", num_locks);
124    lockset.id = (int)getpid();
125    if (!(tmp = getenv("ARENA_DIR"))) tmp = "/tmp";
126    sprintf(arena_name,"%s/armci_arena%d.%ld", tmp,armci_clus_me,lockset.id);
127 
128   (void) usconfig(CONF_ARENATYPE, US_GENERAL);
129   (void) usconfig(CONF_INITUSERS, (unsigned int)
130                   armci_clus_info[armci_clus_me].nslave+1); /* +1 for server */
131    arena_ptr = usinit(arena_name);
132    if(!arena_ptr) armci_die("Failed to Create Arena", 0);
133 
134    for(i=0; i<num_locks; i++){
135        lockset.lock_array[i] = usnewlock(arena_ptr);
136        if(lockset.lock_array[i] == NULL) armci_die("Failed to Create Lock", i);
137    }
138 
139    *lockid = lockset;
140    avail = 1;
141 }
142 
143 
InitLocks(int num_locks,lockset_t lockid)144 void InitLocks(int num_locks, lockset_t lockid)
145 {
146 int i;
147 char *tmp;
148 
149 /*   if(avail) armci_die("Arena already attached", avail); */
150    lockset = lockid;
151    if (!(tmp = getenv("ARENA_DIR"))) tmp = "/tmp";
152    sprintf(arena_name,"%s/armci_arena%d.%ld", tmp,armci_clus_me,lockset.id);
153 
154    (void) usconfig(CONF_ARENATYPE, US_GENERAL);
155    arena_ptr = usinit(arena_name);
156    if(!arena_ptr) armci_die("Failed to Attach to Arena", lockid.id);
157 /*   else fprintf(stderr,	"attached arena %x\n",arena_ptr); */
158 
159    for(i=0; i<num_locks; i++){
160        if(lockset.lock_array[i] == NULL) armci_die("Failed to Attach Lock", i);
161    }
162    avail = 1;
163 }
164 
165 
DeleteLocks(lockset_t lockid)166 void DeleteLocks(lockset_t lockid)
167 {
168  /*  fprintf(stderr,	"deleting arena %x\n",arena_ptr);*/
169   if(!avail)return;
170   else avail = 0;
171   usdetach (arena_ptr);
172   arena_ptr = 0;
173   (void)unlink(arena_name); /*ignore armci_die code:file might be already gone*/
174 }
175 
176 
177 /***************** Convex/HP Exemplar ****************/
178 #elif defined(CONVEX)
179 #include <sys/param.h>
180 #include <sys/file.h>
181 #include <sys/cnx_mman.h>
182 #include <sys/mman.h>
183 #include <sys/types.h>
184 #include <sys/cnx_ail.h>
185 
186 #define FILE_LEN 200
187 lock_t *lock_array;
188 static char file_name[FILE_LEN];
189 static int fd=-1;
190 static unsigned shmem_size=-1;
191 
192 
CreateInitLocks(int num_locks,lockset_t * lockid)193 void CreateInitLocks(int num_locks, lockset_t *lockid)
194 {
195 int i;
196 
197    if(num_locks > NUM_LOCKS) armci_die("To many locks requested", num_locks);
198    *lockid = (int)getpid();
199    sprintf(file_name,"/tmp/ga.locks.%ld", *lockid);
200    if ( (fd = open(file_name, O_RDWR|O_CREAT, 0666)) < 0 )
201       armci_die("CreateInitLocks: failed to open temporary file",0);
202 
203    shmem_size = (NUM_LOCKS)*sizeof(lock_t);
204    lock_array = (lock_t*) mmap((caddr_t) 0, shmem_size,
205                      PROT_READ|PROT_WRITE,
206                      MAP_ANONYMOUS|CNX_MAP_SEMAPHORE|MAP_SHARED, fd, 0);
207 
208    if(((unsigned)lock_array)%16)armci_die("CreateInitLocks: not aligned",0);
209    for (i=0; i<NUM_LOCKS; i++)
210        lock_array[i].state = 0;
211 }
212 
213 
InitLocks(int num_locks,lockset_t lockid)214 void InitLocks(int num_locks, lockset_t  lockid)
215 {
216 int i;
217 
218    if(num_locks > NUM_LOCKS) armci_die("To many locks requested", num_locks);
219    sprintf(file_name,"/tmp/ga.locks.%ld", lockid);
220    if ( (fd = open(file_name, O_RDWR|O_CREAT, 0666)) < 0 )
221       armci_die("InitLocks: failed to open temporary file",0);
222 
223    shmem_size = (NUM_LOCKS)*sizeof(lock_t);
224    lock_array = (lock_t*)  mmap((caddr_t) 0, shmem_size,
225                      PROT_READ|PROT_WRITE,
226                      MAP_ANONYMOUS|CNX_MAP_SEMAPHORE|MAP_SHARED, fd, 0);
227    if(((unsigned)lock_array)%16)armci_die("InitLocks: not aligned",0);
228 }
229 
230 
DeleteLocks(lockset_t lockid)231 void DeleteLocks(lockset_t  lockid)
232 {
233   lock_array = 0;
234   (void)unlink(file_name); /*ignore armci_die code: file might be already gone*/
235   (void)munmap((char *) shmem_size, 0);
236 }
237 
238 
setlock(unsigned * volatile lp)239 void setlock(unsigned * volatile lp)
240 {
241 volatile unsigned flag;
242 
243        flag = fetch_and_inc32(lp);
244        while(flag){
245           flag = fetch32(lp);
246        }
247 }
248 
249 
unsetlock(unsigned * volatile lp)250 void unsetlock(unsigned * volatile lp)
251 {
252        (void)fetch_and_clear32(lp);
253 }
254 
255 
256 #elif defined(WIN32)
257 /****************************** Windows NT ********************************/
258 #include <process.h>
259 #include <windows.h>
260 
261 HANDLE mutex_arr[NUM_LOCKS];
262 static int parent_pid;
263 static int num_alloc_locks=0;
264 
CreateInitLocks(int num_locks,lockset_t * lockid)265 void CreateInitLocks(int num_locks, lockset_t  *lockid)
266 {
267 
268    if(num_locks > NUM_LOCKS) armci_die("To many locks requested", num_locks);
269    *lockid = parent_pid = _getpid();
270 
271    InitLocks(num_locks, *lockid);
272 }
273 
274 
InitLocks(int num_locks,lockset_t lockid)275 void InitLocks(int num_locks, lockset_t lockid)
276 {
277    int i;
278    char lock_name[64];
279 
280    for(i=0;i<num_locks;i++){
281         sprintf(lock_name,"ARMCImutex.%d.%d",(int)lockid,i);
282         mutex_arr[i] = CreateMutex(NULL, FALSE, lock_name);
283         if( mutex_arr[i] == NULL) armci_die("armci_die creating mutexes",i);
284    }
285    num_alloc_locks = num_locks;
286 }
287 
DeleteLocks(lockset_t lockid)288 void DeleteLocks(lockset_t lockid)
289 {
290     int i;
291     for(i=0;i<num_alloc_locks;i++)
292         (void)CloseHandle(mutex_arr[i]);
293 }
294 
setlock(int mutex)295 void setlock(int mutex)
296 {
297     int rc;
298     if(mutex >num_alloc_locks || mutex <0)armci_die("setlock: invalid",mutex);
299     rc =WaitForSingleObject(mutex_arr[mutex],INFINITE);
300 
301     switch(rc) {
302     case WAIT_OBJECT_0:  /* OK */ break;
303     case WAIT_ABANDONED: /*abandoned: some process crashed holding mutex? */
304                         armci_die("setlock: mutex abandoned",mutex);
305     default:            /* some other problem */
306                         fprintf(stderr,"WaitForSingleObject code=%d\n",rc);
307                         armci_die("setlock: failed",mutex);
308     }
309 }
310 
unsetlock(int mutex)311 void unsetlock(int mutex)
312 {
313     if(mutex >num_alloc_locks || mutex <0)armci_die("unsetlock: invalid",mutex);
314     if(ReleaseMutex(mutex_arr[mutex])==FALSE)armci_die("unsetlock: failed",mutex);
315 }
316 
317 
318 #elif defined(CRAY_YMP)
319 
320 lock_t  cri_l[NUM_LOCKS];
321 #pragma  _CRI common cri_l
322 
CreateInitLocks(int num_locks,lockset_t * lockid)323 void CreateInitLocks(int num_locks, lockset_t  *lockid)
324 {
325    int i;
326    if(num_locks > NUM_LOCKS) armci_die("To many locks requested", num_locks);
327 
328    for(i=0;i<num_locks;i++)cri_l[i]=0;
329 }
330 
331 
InitLocks(int num_locks,lockset_t lockid)332 void InitLocks(int num_locks, lockset_t lockid)
333 {
334 }
335 
336 
DeleteLocks(lockset_t lockid)337 void DeleteLocks(lockset_t lockid)
338 {
339 }
340 
341 #else
342 /*********************** every thing else *************************/
343 
CreateInitLocks(int num_locks,lockset_t * lockid)344 void CreateInitLocks(int num_locks, lockset_t  *lockid)
345 {}
346 
InitLocks(int num_locks,lockset_t lockid)347 void InitLocks(int num_locks, lockset_t lockid)
348 {
349 }
350 
351 
DeleteLocks(lockset_t lockid)352 void DeleteLocks(lockset_t lockid)
353 {
354 }
355 
356 #endif
357 
358