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