~ubuntu-branches/ubuntu/utopic/nwchem/utopic

« back to all changes in this revision

Viewing changes to src/tools/ga-5-2/armci/tcgmsg/ipcv4.0/sema.c

  • Committer: Package Import Robot
  • Author(s): Michael Banck, Daniel Leidert, Andreas Tille, Michael Banck
  • Date: 2013-07-04 12:14:55 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20130704121455-5tvsx2qabor3nrui
Tags: 6.3-1
* New upstream release.
* Fixes anisotropic properties (Closes: #696361).
* New features include:
  + Multi-reference coupled cluster (MRCC) approaches
  + Hybrid DFT calculations with short-range HF 
  + New density-functionals including Minnesota (M08, M11) and HSE hybrid
    functionals
  + X-ray absorption spectroscopy (XAS) with TDDFT
  + Analytical gradients for the COSMO solvation model
  + Transition densities from TDDFT 
  + DFT+U and Electron-Transfer (ET) methods for plane wave calculations
  + Exploitation of space group symmetry in plane wave geometry optimizations
  + Local density of states (LDOS) collective variable added to Metadynamics
  + Various new XC functionals added for plane wave calculations, including
    hybrid and range-corrected ones
  + Electric field gradients with relativistic corrections 
  + Nudged Elastic Band optimization method
  + Updated basis sets and ECPs 

[ Daniel Leidert ]
* debian/watch: Fixed.

[ Andreas Tille ]
* debian/upstream: References

[ Michael Banck ]
* debian/upstream (Name): New field.
* debian/patches/02_makefile_flags.patch: Refreshed.
* debian/patches/06_statfs_kfreebsd.patch: Likewise.
* debian/patches/07_ga_target_force_linux.patch: Likewise.
* debian/patches/05_avoid_inline_assembler.patch: Removed, no longer needed.
* debian/patches/09_backported_6.1.1_fixes.patch: Likewise.
* debian/control (Build-Depends): Added gfortran-4.7 and gcc-4.7.
* debian/patches/10_force_gcc-4.7.patch: New patch, explicitly sets
  gfortran-4.7 and gcc-4.7, fixes test suite hang with gcc-4.8 (Closes:
  #701328, #713262).
* debian/testsuite: Added tests for COSMO analytical gradients and MRCC.
* debian/rules (MRCC_METHODS): New variable, required to enable MRCC methods.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#if HAVE_CONFIG_H
 
2
#   include "config.h"
 
3
#endif
 
4
 
 
5
/* $Header: /tmp/hpctools/ga/tcgmsg/ipcv4.0/sema.c,v 1.17 2003-05-08 15:44:43 edo Exp $ */
 
6
 
 
7
/*
 
8
  These routines simplify the interface to semaphores for use in mutual
 
9
  exclusion and queuing. Hopefully I can also make this portable.
 
10
 
 
11
  An external routine Error is assumed which is called upon an error
 
12
  and tidies up by calling SemSetDestroyAll.
 
13
 
 
14
  In most cases errors cause an internal hard failure (by calling Error).
 
15
 
 
16
  1) make an array of n_sem semaphores, returning the id associated
 
17
     with the entire set. All the semaphore values are initialized to value
 
18
     which should be a positve integer (queuing) or 0 (synchronization).
 
19
     The semaphores in the set are indexed from 0 to n_sem-1.
 
20
 
 
21
     long SemSetCreate(long n_sem, long value)
 
22
 
 
23
  2) Decrement and test the value associated with the semaphore specified by 
 
24
     (sem_set_id, sem_num). In effect this:
 
25
 
 
26
     if (value >= 0) {
 
27
        continue execution
 
28
     }
 
29
     else {
 
30
        wait in queue for the semaphore
 
31
     }
 
32
     decrement value
 
33
 
 
34
     void SemWait(long sem_set_id, long sem_num)
 
35
 
 
36
  3) Increment the value associated with the semaphore specified by
 
37
     (sem_set_id, sem_num). If value <= 0 (i.e. there are processes
 
38
     in the queue) this releases the next process.
 
39
 
 
40
     void SemPost(long sem_set_id, long sem_num)
 
41
     
 
42
  4) Return the current value associated with the semaphore sepcified by
 
43
     (sem_set_id, sem_num).
 
44
 
 
45
     long SemValue(long sem_set_id, long sem_num)
 
46
 
 
47
  5) Destroy the set of semaphores. Any other processes that are accessing
 
48
     or try to access the semaphore set should get an error.
 
49
     On the SUN (all system V machines?) the semaphore sets should
 
50
     be destroyed explicitly before the final process exits.
 
51
     0 is returned if OK. -1 implies an error.
 
52
 
 
53
     long SemSetDestroy(long sem_set_id)
 
54
 
 
55
  6) Destroy all the semaphore sets that are known about. This is really
 
56
     meant for an error routine to call to try and tidy up. Though all
 
57
     applications could call it before the last process exits.
 
58
     0 is returned if OK. -1 implies an error.
 
59
 
 
60
     long SemSetDestroyAll()
 
61
*/
 
62
 
 
63
extern void Error();
 
64
 
 
65
#if defined(SYSV) && !defined SGIUS  && !defined(SPPLOCKS) && !defined(MACX)
 
66
 
 
67
/********************************************************************
 
68
  Most system V compatible machines
 
69
 ********************************************************************/
 
70
 
 
71
/* 
 
72
 
 
73
   The value used for our semaphore is equal to the value of the
 
74
   System V semaphore (which is always positive) minus the no. of
 
75
   processes in the queue. That is because our interface was modelled
 
76
   after that of Alliant whose semaphore can take on negative values.
 
77
*/
 
78
 
 
79
#include <sys/types.h>
 
80
#include <sys/ipc.h>
 
81
#include <sys/sem.h>
 
82
 
 
83
#if !HAVE_UNION_SEMUN
 
84
union semun {
 
85
        int val;                    /* value for SETVAL */
 
86
        struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
 
87
        unsigned short int *array;  /* array for GETALL, SETALL */
 
88
        struct seminfo *__buf;      /* buffer for IPC_INFO */
 
89
};
 
90
#endif
 
91
 
 
92
/* this global structure maintains a list of allocated semaphore sets
 
93
   which is used for SemSetDestroyAll */
 
94
 
 
95
#define MAX_SEM_SETS 20
 
96
static int sem_set_id_list[MAX_SEM_SETS];
 
97
static int num_sem_set = 0;
 
98
 
 
99
#if defined(SGITFP) || defined(SGI64) || defined(KSR) || defined(SOLARIS) || defined (AIX) || defined(LINUX64)
 
100
#   define MAX_N_SEM 512 
 
101
#else
 
102
#   define MAX_N_SEM 40
 
103
#endif
 
104
 
 
105
void InitSemSetList()
 
106
/* Initialise sem_set_id_list */
 
107
{
 
108
  int i;
 
109
  
 
110
  for (i=0; i<MAX_SEM_SETS; i++)
 
111
    sem_set_id_list[i] = -1;
 
112
}
 
113
 
 
114
long SemSetCreate(n_sem, value)
 
115
     long n_sem;
 
116
     long value;
 
117
{
 
118
  int semid, i;
 
119
  union semun arg;
 
120
 
 
121
  /* Check for errors and initialise data if first entry */
 
122
 
 
123
  if ( (n_sem <= 0) || (n_sem >= MAX_N_SEM) )
 
124
    Error("SemSetCreate: n_sem has invalid value", (long) n_sem);
 
125
 
 
126
  if (num_sem_set == 0)
 
127
    InitSemSetList();
 
128
  else if (num_sem_set >= MAX_SEM_SETS)
 
129
    Error("SemSetCreate: Exceeded man no. of semaphore sets",
 
130
          (long) num_sem_set);
 
131
 
 
132
  /* Actually make the semaphore set */
 
133
 
 
134
  if ( (semid = semget(IPC_PRIVATE, (int) n_sem, IPC_CREAT | 00600)) < 0)
 
135
    Error("SemSetCreate: failed to create semaphore set", (long) semid);
 
136
 
 
137
  /* Put the semid in the first empty slot in sem_set_id_list */
 
138
 
 
139
  for (i=0; i < MAX_SEM_SETS; i++) {
 
140
    if (sem_set_id_list[i] == -1) {
 
141
      sem_set_id_list[i] = semid;
 
142
      break;
 
143
    }
 
144
  }
 
145
  if (i == MAX_SEM_SETS)
 
146
    Error("SemSetCreate: internal error puting semid in list", (long) i);
 
147
 
 
148
  num_sem_set++;
 
149
 
 
150
  /* Now set the value of all the semaphores */
 
151
 
 
152
  arg.val = (int) value;
 
153
  for (i=0; i<n_sem; i++)
 
154
    if (semctl(semid, i, SETVAL, arg) == -1)
 
155
      Error("SemSetCreate: error setting value for semaphore", (long) i);
 
156
 
 
157
  return semid;
 
158
}
 
159
 
 
160
void SemWait(sem_set_id, sem_num)
 
161
     long sem_set_id;
 
162
     long sem_num;
 
163
{
 
164
  struct sembuf sops;
 
165
 
 
166
  sops.sem_num = sem_num;   /* semaphore no. */
 
167
  sops.sem_op = -1;         /* decrement by 1 */
 
168
  sops.sem_flg = 0;         /* block */
 
169
 
 
170
  if (semop((int) sem_set_id, &sops, 1) == -1)
 
171
    Error("SemWait: error from semop", (long) -1);
 
172
}
 
173
 
 
174
void SemPost(sem_set_id, sem_num)
 
175
     long sem_set_id;
 
176
     long sem_num;
 
177
{
 
178
  struct sembuf sops;
 
179
 
 
180
  sops.sem_num = sem_num;   /* semaphore no. */
 
181
  sops.sem_op =  1;         /* increment by 1 */
 
182
  sops.sem_flg = 0;         /* not used? */
 
183
 
 
184
  if (semop((int) sem_set_id, &sops, 1) == -1)
 
185
    Error("SemPost: error from semop", (long) -1);
 
186
}
 
187
 
 
188
long SemValue(sem_set_id, sem_num)
 
189
     long sem_set_id;
 
190
     long sem_num;
 
191
{
 
192
  /* See note at top of SUN code section about semaphore value */
 
193
 
 
194
  union semun arg;
 
195
  int semval, semncnt;
 
196
  
 
197
  if ( (semval = semctl((int) sem_set_id, (int) sem_num, GETVAL, arg)) == -1)
 
198
    Error("SemValue: error getting value for semaphore", (long) sem_num);
 
199
  
 
200
  if ( (semncnt = semctl((int) sem_set_id, (int) sem_num, GETNCNT, arg)) == -1)
 
201
    Error("SemValue: error getting ncnt for semaphore", (long) sem_num);
 
202
  
 
203
  return semval-semncnt;
 
204
}
 
205
 
 
206
long SemSetDestroy(sem_set_id)
 
207
     long sem_set_id;
 
208
{
 
209
  union semun arg;
 
210
  int i;
 
211
 
 
212
 /* Remove the sem_set_id from the internal list of ids */
 
213
 
 
214
  for (i=0; i<MAX_SEM_SETS; i++)
 
215
    if (sem_set_id_list[i] == sem_set_id) {
 
216
      sem_set_id_list[i] = -1;
 
217
      break;
 
218
    }
 
219
 
 
220
  num_sem_set--;
 
221
 
 
222
  /* System call to delete the id */
 
223
  
 
224
  return (long) semctl((int) sem_set_id, 0, IPC_RMID, arg);
 
225
}
 
226
  
 
227
long SemSetDestroyAll()
 
228
{
 
229
  long i, status=0;
 
230
 
 
231
  for (i=0; i<MAX_SEM_SETS; i++)
 
232
    if (sem_set_id_list[i] != -1)
 
233
      status += SemSetDestroy((long) sem_set_id_list[i]);
 
234
 
 
235
  if (status)
 
236
    status = -1;
 
237
 
 
238
  return status;
 
239
}
 
240
 
 
241
#endif
 
242
 
 
243
#ifdef ALLIANT
 
244
/*************************************************************
 
245
    Alliant Concentrix 5.0 and Concentrix FX/2800
 
246
 *************************************************************/
 
247
 
 
248
/* This is very specific to the Alliant. */
 
249
 
 
250
#include <sys/rtsem.h>
 
251
#include <sys/errno.h>
 
252
 
 
253
extern int errno;
 
254
 
 
255
/* On the alliant semaphores are handed out one at a time rather than
 
256
   in sets, so have to maintain sets manually */
 
257
 
 
258
#define MAX_SEM_SETS 20
 
259
#define MAX_N_SEM 128
 
260
 
 
261
static struct sem_set_list_struct {
 
262
  int id[MAX_N_SEM];                       /* alliant semaphore id */
 
263
  int n_sem;                               /* no. of semaphores in set */
 
264
} sem_set_list[MAX_SEM_SETS];
 
265
 
 
266
static int num_sem_set = 0;
 
267
 
 
268
 
 
269
void InitSemSetList()
 
270
/* Initialise sem_set_list */
 
271
{
 
272
  int i, j;
 
273
  
 
274
  for (i=0; i<MAX_SEM_SETS; i++) {
 
275
    sem_set_list[i].n_sem = 0;
 
276
    for (j=0; j<MAX_N_SEM; j++)
 
277
      sem_set_list[i].id[j] = -1;
 
278
  }
 
279
}
 
280
 
 
281
long SemSetCreate(n_sem, value)
 
282
     long n_sem;
 
283
     long value;
 
284
{
 
285
  int semid, i, j;
 
286
 
 
287
  /* Check for errors and initialise data if first entry */
 
288
 
 
289
  if ( (n_sem <= 0) || (n_sem >= MAX_N_SEM) )
 
290
    Error("SemSetCreate: n_sem has invalid value", (long) n_sem);
 
291
 
 
292
  if (num_sem_set == 0)
 
293
    InitSemSetList();
 
294
  else if (num_sem_set >= MAX_SEM_SETS)
 
295
    Error("SemSetCreate: Exceeded man no. of semaphore sets",
 
296
          (long) num_sem_set);
 
297
 
 
298
  /* Find first empty slot in sem_set_list */
 
299
 
 
300
  for (i=0; i < MAX_SEM_SETS; i++) 
 
301
    if (sem_set_list[i].n_sem == 0)
 
302
      break;
 
303
 
 
304
  if (i == MAX_SEM_SETS)
 
305
    Error("SemSetCreate: internal error puting semid in list", (long) i);
 
306
 
 
307
  /* Actually make the semaphore set */
 
308
 
 
309
  for (j=0; j<n_sem; j++) {
 
310
    if ( (semid = sem_create(value, value, SEMQUE_FIFO, 0)) < 0)
 
311
      Error("SemSetCreate: failed to create semaphore", (long) j);
 
312
    sem_set_list[i].id[j] = semid;
 
313
  }
 
314
 
 
315
  num_sem_set++;
 
316
  
 
317
  return i;
 
318
}
 
319
 
 
320
void SemWait(sem_set_id, sem_num)
 
321
     long sem_set_id;
 
322
     long sem_num;
 
323
{
 
324
interrupted:
 
325
  if (sem_wait(sem_set_list[sem_set_id].id[sem_num]) < 0) {
 
326
    if (errno == EINTR)
 
327
      goto interrupted;   /* got zapped by a signal ... try again */
 
328
    else
 
329
      Error("SemWait: error from sem_wait", (long) -1);
 
330
  }
 
331
}
 
332
 
 
333
void SemPost(sem_set_id, sem_num)
 
334
     long sem_set_id;
 
335
     long sem_num;
 
336
{
 
337
  if (sem_post(sem_set_list[sem_set_id].id[sem_num]) < 0)
 
338
    Error("SemPost: error from sem_post", (long) -1);
 
339
}
 
340
 
 
341
long SemValue(sem_set_id, sem_num)
 
342
     long sem_set_id;
 
343
     long sem_num;
 
344
{
 
345
  SEM_INFO info;
 
346
 
 
347
  if (sem_info(sem_set_list[sem_set_id].id[sem_num], &info, sizeof info) < 0)
 
348
    Error("SemValue: error from sem_info", (long) -1);
 
349
 
 
350
  return info.curval;
 
351
}
 
352
 
 
353
long SemSetDestroy(sem_set_id)
 
354
     long sem_set_id;
 
355
{
 
356
  int status=0, i;
 
357
 
 
358
  /* Close each semaphore in the set */
 
359
 
 
360
  for (i=0; i<sem_set_list[sem_set_id].n_sem; i++) {
 
361
    status += sem_destroy(sem_set_list[sem_set_id].id[i]);
 
362
    sem_set_list[sem_set_id].id[i] = -1;
 
363
  }
 
364
 
 
365
  sem_set_list[sem_set_id].n_sem = 0;
 
366
 
 
367
  num_sem_set--;
 
368
 
 
369
  if (status)
 
370
    status = -1;
 
371
 
 
372
  return (long) status;
 
373
}
 
374
  
 
375
long SemSetDestroyAll()
 
376
{
 
377
  int i, status=0;
 
378
 
 
379
  for (i=0; i<MAX_SEM_SETS; i++)
 
380
    if (sem_set_list[i].n_sem)
 
381
      status += SemSetDestroy(i);
 
382
 
 
383
  if (status)
 
384
    status = -1;
 
385
 
 
386
  return (long) status;
 
387
}
 
388
 
 
389
#endif
 
390
#if (defined(CONVEX) || defined(APOLLO)) && !defined(HPUX)
 
391
 
 
392
#include <stdio.h>
 
393
#include <sys/param.h>
 
394
#include <sys/file.h>
 
395
#include <sys/mman.h>
 
396
#include <sys/types.h>
 
397
 
 
398
#define MAX_SEM_SETS 20
 
399
#define MAX_N_SEM 100
 
400
 
 
401
/* On the convex a semaphore is a structure but on the apollo
 
402
   it is an array which does not need dereferencing.  Use ADDR
 
403
   to generate the address of a semaphore */
 
404
#ifdef APOLLO
 
405
#define ADDR(x) x
 
406
#else
 
407
#define ADDR(x) &x
 
408
#endif
 
409
 
 
410
extern char *mktemp();
 
411
 
 
412
struct sem_set_struct {
 
413
  int n_sem;                    /* no. of semaphores in set */
 
414
  semaphore lock[MAX_N_SEM];    /* locks for changing value */
 
415
  semaphore wait[MAX_N_SEM];    /* locks for queing */
 
416
  int value[MAX_N_SEM];         /* values */
 
417
};
 
418
 
 
419
static int num_sem_set = 0;
 
420
static struct sem_set_struct *sem_sets;
 
421
static int fd = -1;
 
422
static char template[] = "/tmp/SEMA.XXXXXX";
 
423
static char *filename = (char *) NULL;
 
424
 
 
425
void InitSemSets()
 
426
/* Initialise sem_sets and allocate associated shmem region */
 
427
{
 
428
  int i, j;
 
429
  unsigned size = sizeof(struct sem_set_struct) * MAX_SEM_SETS;
 
430
 
 
431
#ifndef APOLLO
 
432
  /* Generate scratch file to identify region ... mustn't do this
 
433
     on the APOLLO */
 
434
 
 
435
  filename = mktemp(template);
 
436
  if ( (fd = open(filename, O_RDWR|O_CREAT, 0666)) < 0 )
 
437
    Error("InitSemSets: failed to open temporary file",0);
 
438
#endif
 
439
 
 
440
  sem_sets = (struct sem_set_struct *) mmap((caddr_t) 0, &size,
 
441
                     PROT_READ|PROT_WRITE,
 
442
                     MAP_ANON|MAP_HASSEMAPHORE|MAP_SHARED, fd, 0);
 
443
 
 
444
#ifdef APOLLO
 
445
  if (sem_sets == (struct sem_set_struct *) 0)
 
446
    Error("InitSemSets: mmap failed", (long) -1);
 
447
#else
 
448
  if (sem_sets == (struct sem_set_struct *) -1)
 
449
    Error("InitSemSets: mmap failed", (long) -1);
 
450
#endif
 
451
 
 
452
  for (i=0; i<MAX_SEM_SETS; i++) {
 
453
    sem_sets[i].n_sem = 0;
 
454
    for (j=0; j<MAX_N_SEM; j++) {
 
455
      mclear(ADDR(sem_sets[i].lock[j]));
 
456
      mclear(ADDR(sem_sets[i].wait[j]));
 
457
      sem_sets[i].value[j] = 0;
 
458
    }
 
459
  }
 
460
}
 
461
 
 
462
long SemSetCreate(n_sem, value)
 
463
     long n_sem;
 
464
     long value;
 
465
{
 
466
  int i;
 
467
 
 
468
  /* Check for errors and initialise data if first entry */
 
469
 
 
470
  if ( (n_sem <= 0) || (n_sem >= MAX_N_SEM) )
 
471
    Error("SemSetCreate: n_sem has invalid value",n_sem);
 
472
 
 
473
  if (num_sem_set == 0)
 
474
    InitSemSets();
 
475
  else if (num_sem_set >= MAX_SEM_SETS)
 
476
    Error("SemSetCreate: Exceeded man no. of semaphore sets",
 
477
          num_sem_set);
 
478
 
 
479
  /* Initialize the values */
 
480
 
 
481
  for (i=0; i<n_sem; i++)
 
482
    sem_sets[num_sem_set].value[i] = value;
 
483
 
 
484
  sem_sets[num_sem_set].n_sem = n_sem;
 
485
 
 
486
  num_sem_set++;
 
487
 
 
488
  return (long) (num_sem_set - 1);
 
489
}
 
490
 
 
491
void SemWait(sem_set_id, sem_num)
 
492
     long sem_set_id;
 
493
     long sem_num;
 
494
{
 
495
  if ( (sem_set_id < 0) || (sem_set_id >= num_sem_set) )
 
496
    Error("SemWait: invalid sem_set_id",sem_set_id);
 
497
  if ( (sem_num < 0) || (sem_num >= sem_sets[sem_set_id].n_sem) )
 
498
    Error("SemWait: invalid semaphore number in set",sem_num);
 
499
 
 
500
  while (1) {
 
501
 
 
502
    /* Get the lock around the whole semaphore */
 
503
 
 
504
    (void) mset(ADDR(sem_sets[sem_set_id].lock[sem_num]), 1);
 
505
 
 
506
    /* If the value is positive fall thru, else wait */
 
507
 
 
508
    if (sem_sets[sem_set_id].value[sem_num] > 0)
 
509
      break;
 
510
    else {
 
511
      (void) mclear(ADDR(sem_sets[sem_set_id].lock[sem_num]));
 
512
      (void) mset(ADDR(sem_sets[sem_set_id].wait[sem_num]), 1);
 
513
    }
 
514
  }
 
515
 
 
516
  /* Are ready to go ... decrement the value and release lock */
 
517
 
 
518
  sem_sets[sem_set_id].value[sem_num]--;
 
519
  (void) mclear(ADDR(sem_sets[sem_set_id].lock[sem_num]));
 
520
 
 
521
}
 
522
 
 
523
void SemPost(sem_set_id, sem_num)
 
524
     long sem_set_id;
 
525
     long sem_num;
 
526
{
 
527
  int i;
 
528
 
 
529
  if ( (sem_set_id < 0) || (sem_set_id >= num_sem_set) )
 
530
    Error("SemPost: invalid sem_set_id",sem_set_id);
 
531
  if ( (sem_num < 0) || (sem_num >= sem_sets[sem_set_id].n_sem) )
 
532
    Error("SemPost: invalid semaphore number in set",sem_num);
 
533
 
 
534
  /* Get the lock around the whole semaphore */
 
535
 
 
536
  (void) mset(ADDR(sem_sets[sem_set_id].lock[sem_num]), 1);
 
537
  
 
538
  /* Read and increment the value. If is now zero wake up
 
539
     up the queue */
 
540
 
 
541
  sem_sets[sem_set_id].value[sem_num]++;
 
542
  i = sem_sets[sem_set_id].value[sem_num];
 
543
 
 
544
  (void) mclear(ADDR(sem_sets[sem_set_id].lock[sem_num]));
 
545
  if (i >= 0)
 
546
    (void) mclear(ADDR(sem_sets[sem_set_id].wait[sem_num]));
 
547
}
 
548
 
 
549
long SemValue(sem_set_id, sem_num)
 
550
     long sem_set_id;
 
551
     long sem_num;
 
552
{
 
553
  int i;
 
554
 
 
555
  if ( (sem_set_id < 0) || (sem_set_id >= num_sem_set) )
 
556
    Error("SemValue: invalid sem_set_id",sem_set_id);
 
557
  if ( (sem_num < 0) || (sem_num >= sem_sets[sem_set_id].n_sem) )
 
558
    Error("SemValue: invalid semaphore number in set",sem_num);
 
559
 
 
560
  /* There seems no point in getting the lock just to read
 
561
     the value and it seems more useful not to (e.g. debugging) */
 
562
 
 
563
  i = sem_sets[sem_set_id].value[sem_num];
 
564
 
 
565
  return (long) (i-1);
 
566
}
 
567
 
 
568
long SemSetDestroy(sem_set_id)
 
569
     long sem_set_id;
 
570
{
 
571
 
 
572
  if ( (sem_set_id < 0) || (sem_set_id >= num_sem_set) )
 
573
    return -1;
 
574
 
 
575
  sem_sets[sem_set_id].n_sem = 0;
 
576
 
 
577
  return (long) 0;
 
578
}
 
579
  
 
580
long SemSetDestroyAll()
 
581
{
 
582
  long i, status=0;
 
583
 
 
584
  for (i=0; i<num_sem_set; i++)
 
585
    if (sem_sets[i].n_sem)
 
586
      status += SemSetDestroy(i);
 
587
 
 
588
  if (fd >= 0) {
 
589
    (void) close(fd);
 
590
    fd = -1;
 
591
    (void) unlink(filename);
 
592
  }
 
593
 
 
594
  status += munmap((char *) sem_sets, 0);
 
595
 
 
596
  if (status)
 
597
    status = -1;
 
598
 
 
599
  return status;
 
600
}
 
601
 
 
602
#endif
 
603
 
 
604
 
 
605
#if defined(SGIUS) || defined(SPPLOCKS)
 
606
 
 
607
/*
 
608
  SGI fast US library semaphores ... aren't any faster
 
609
  than system V semaphores ... implement using spin locks
 
610
*/
 
611
 
 
612
#include <stdio.h>
 
613
#include <unistd.h>  
 
614
#define MAX_SEMA 512
 
615
static volatile int *val;
 
616
#define NAME_LEN 200
 
617
 
 
618
#ifdef SGI
 
619
# include <ulocks.h>
 
620
  static usptr_t *arena_ptr;
 
621
  static ulock_t *locks[MAX_SEMA];
 
622
  static char arena_name[NAME_LEN];
 
623
# define EIGHT 8
 
624
# define LOCK ussetlock
 
625
# define UNLOCK usunsetlock
 
626
#define  JUMP EIGHT
 
627
 
 
628
#include "sndrcvP.h"
 
629
 
 
630
extern char *getenv(const char *);
 
631
 
 
632
long SemSetCreate(long n_sem, long value)
 
633
{
 
634
  int i;
 
635
  char *tmp;
 
636
  if (!(tmp = getenv("ARENA_DIR"))) tmp = "/tmp";
 
637
 
 
638
   sprintf(arena_name,"%s/tcgmsg.arena.%ld",tmp, (long)getpid()); 
 
639
#ifdef PRIVATE_ARENA
 
640
   (void) usconfig(CONF_ARENATYPE, US_SHAREDONLY);
 
641
#endif
 
642
   (void) usconfig(CONF_INITUSERS, (unsigned int)SR_clus_info[SR_clus_id].nslave );
 
643
#ifdef SGI
 
644
    (void) usconfig(CONF_INITSIZE, 1024*1024);
 
645
#endif
 
646
 
 
647
  if (!(arena_ptr = usinit(arena_name)))
 
648
    Error("SemSetCreate: failed to create arena", 0L);
 
649
 
 
650
  /* Magic factors of EIGHT here to ensure that values are
 
651
     in different cache lines to avoid aliasing -- good on SGI and Convex */
 
652
 
 
653
  if (!(val = (int *) usmalloc(EIGHT*MAX_SEMA*sizeof(int), arena_ptr)))
 
654
    Error("SemSetCreate: failed to get shmem", (long) (MAX_SEMA*sizeof(int)));
 
655
 
 
656
  for (i=0; i<n_sem; i++) {
 
657
    if (!(locks[i] = usnewlock(arena_ptr)))
 
658
      Error("SemSetCreate: failed to create lock", (long) i);
 
659
    val[i*EIGHT] = (int) value;
 
660
  }
 
661
  return 1L;
 
662
}
 
663
 
 
664
long SemSetDestroyAll()
 
665
{
 
666
/*  usdetach (arena_ptr);*/
 
667
  arena_ptr = 0;
 
668
  unlink(arena_name);
 
669
  return 0;
 
670
}
 
671
 
 
672
#endif
 
673
 
 
674
 
 
675
#ifdef SPPLOCKS
 
676
#include <sys/param.h>
 
677
#include <sys/file.h>
 
678
#include <sys/cnx_mman.h>
 
679
#include <sys/mman.h>
 
680
#include <sys/types.h>
 
681
 
 
682
#define SIXTEEN 16
 
683
#define JUMP SIXTEEN
 
684
typedef struct{
 
685
        int state;
 
686
        int pad[15]; 
 
687
} lock_t;
 
688
 
 
689
static lock_t *locks;
 
690
 
 
691
#  define    LOCK(x) set_lock(&x.state)
 
692
#  define  UNLOCK(x) unset_lock(&x.state)
 
693
#  define INILOCK(x) init_lock(&x.state)
 
694
 
 
695
 
 
696
void init_lock(int * volatile ip)
 
697
{
 
698
    *ip = 1;
 
699
}
 
700
 
 
701
void set_lock(int * volatile ip)
 
702
{
 
703
    while (1) {
 
704
        while (!(*ip));
 
705
        if (__ldcws32(ip))
 
706
                        break;
 
707
    }
 
708
}
 
709
 
 
710
void unset_lock(int *ip)
 
711
{
 
712
  *ip = 1;
 
713
  asm("sync");
 
714
}
 
715
 
 
716
static int fd = -1;
 
717
static char template[] = "/tmp/SEMA.XXXXXX";
 
718
static char *filename = (char *) NULL;
 
719
static unsigned shmem_size;
 
720
 
 
721
long SemSetCreate(long n_sem, long value)
 
722
{
 
723
  int i;
 
724
  shmem_size = SIXTEEN*MAX_SEMA*sizeof(int)+MAX_SEMA*sizeof(lock_t);
 
725
 
 
726
  if ( (n_sem <= 0) || (n_sem >= MAX_SEMA) )
 
727
    Error("SemSetCreate: n_sem has invalid value",n_sem);
 
728
 
 
729
  /* allocate shared memory for locks and semaphore val */
 
730
  filename = mktemp(template);
 
731
  if ( (fd = open(filename, O_RDWR|O_CREAT, 0666)) < 0 )
 
732
    Error("SemSetCreate: failed to open temporary file",0);
 
733
  val = (int *) mmap((caddr_t) 0, shmem_size,
 
734
                     PROT_READ|PROT_WRITE,
 
735
                     MAP_ANONYMOUS|CNX_MAP_SEMAPHORE|MAP_SHARED, fd, 0);
 
736
  locks = (lock_t*)( val + SIXTEEN*MAX_SEMA);
 
737
 
 
738
  /* initialize locks and semaphore values */
 
739
  for (i=0; i<n_sem; i++) {
 
740
    INILOCK(locks[i]);
 
741
    val[i*SIXTEEN] = (int) value;
 
742
  }
 
743
  return 1L;
 
744
}
 
745
 
 
746
long SemSetDestroyAll()
 
747
{
 
748
  long status=0;
 
749
  if((int)unlink(filename)==-1)Error("SemSetDestroyAll: unlink failed",0);
 
750
  status = munmap((char *) shmem_size, 0);
 
751
  if(status)status = -1;
 
752
  return status;
 
753
}
 
754
 
 
755
#endif
 
756
 
 
757
 
 
758
double __tcgmsg_fred__=0.0;
 
759
 
 
760
void Dummy()
 
761
{
 
762
  int n = 200;                  /* This seems optimal */
 
763
  while(n--)
 
764
    __tcgmsg_fred__++;
 
765
}
 
766
 
 
767
void SemWait(long sem_set_id, long sem_num)
 
768
{
 
769
  int value = 0;
 
770
  int off = sem_num*JUMP;
 
771
 
 
772
  if ( (sem_num < 0) || (sem_num >= MAX_SEMA) )
 
773
    Error("SemWait: invalid sem_num",sem_num);
 
774
 
 
775
  while (value<=0) {
 
776
    LOCK(locks[sem_num]);
 
777
    value = val[off];
 
778
    if (value>0)
 
779
      val[off]--;
 
780
    UNLOCK(locks[sem_num]);
 
781
    if (value<=0) 
 
782
      Dummy();
 
783
  }
 
784
}
 
785
 
 
786
void SemPost(long sem_set_id, long sem_num)
 
787
{
 
788
  int off = sem_num*JUMP;
 
789
  if ( (sem_num < 0) || (sem_num >= MAX_SEMA) )
 
790
    Error("SemPost: invalid sem_num",sem_num);
 
791
 
 
792
  LOCK(locks[sem_num]);
 
793
  val[off]++;
 
794
  UNLOCK(locks[sem_num]);
 
795
}
 
796
 
 
797
long SemValue(long sem_set_id, long sem_num)
 
798
{
 
799
  Error("SemValue: not implemented", sem_num);
 
800
  return 1;
 
801
}
 
802
 
 
803
long SemSetDestroy(long sem_set_id)
 
804
{
 
805
  return(SemSetDestroyAll());
 
806
}
 
807
 
 
808
#endif
 
809
 
 
810
 
 
811
#if defined(MACX)
 
812
 
 
813
 
 
814
#include <unistd.h>
 
815
#include <sys/fcntl.h>
 
816
#include <sys/types.h>
 
817
#include <sys/mman.h>
 
818
#include <sys/semaphore.h>
 
819
 
 
820
#define MAX_SEMA 32
 
821
static int fd = -1;
 
822
static char template[] = "/tmp/SEMA.XXXXXX";
 
823
static char *filename = (char *) NULL;
 
824
static unsigned shmem_size;
 
825
 
 
826
#if defined(NAMED_SEMAPHORES_SUPPORTED)
 
827
 
 
828
static sem_t *sem_arr;
 
829
 
 
830
long SemSetCreate(long n_sem, long value)
 
831
{
 
832
  int i;
 
833
  shmem_size = MAX_SEMA*sizeof(sem_t);
 
834
 
 
835
  if ( (n_sem <= 0) || (n_sem >= MAX_SEMA) )
 
836
    Error("SemSetCreate: n_sem has invalid value",n_sem);
 
837
 
 
838
  /* allocate shared memory for locks and semaphore val */
 
839
  filename = mktemp(template);
 
840
  if ( (fd = shm_open(filename, O_CREAT|O_RDWR, 0666)) < 0 )
 
841
    Error("SemSetCreate: failed to open temporary shm file",0);
 
842
  sem_arr = (sem_t*) mmap((caddr_t)0, shmem_size, PROT_READ|PROT_WRITE,
 
843
                     MAP_ANON|MAP_HASSEMAPHORE|MAP_SHARED, fd, (off_t)0);
 
844
  if(!sem_arr)Error("SemSetCreate: failed to mmap",0);
 
845
 
 
846
  /* initialize locks and semaphore values */
 
847
  for (i=0; i<n_sem; i++) {
 
848
      if(sem_init(sem_arr+i,1,1)<0)
 
849
             Error("SemSetCreate: sem_init failed",(long)i);
 
850
  }
 
851
  return 1L;
 
852
}
 
853
 
 
854
long SemSetDestroyAll()
 
855
{
 
856
  long status=0;
 
857
  if((int)unlink(filename)==-1)Error("SemSetDestroyAll: unlink failed",0);
 
858
  status = munmap((char *) shmem_size, 0);
 
859
  if(status)status = -1;
 
860
  return status;
 
861
}
 
862
 
 
863
 
 
864
void SemWait(long sem_set_id, long sem_num)
 
865
{
 
866
  if ( (sem_num < 0) || (sem_num >= MAX_SEMA) )
 
867
    Error("SemWait: invalid sem_num",sem_num);
 
868
  if(sem_wait(sem_arr+sem_num)<0)
 
869
    Error("SemWait: failed",sem_num);
 
870
}
 
871
 
 
872
void SemPost(long sem_set_id, long sem_num)
 
873
 
874
  if ( (sem_num < 0) || (sem_num >= MAX_SEMA) )
 
875
    Error("SemPost: invalid sem_num",sem_num);
 
876
  if(sem_post(sem_arr+sem_num)<0)
 
877
    Error("SemPost: failed",sem_num);
 
878
 
 
879
}
 
880
  
 
881
long SemValue(long sem_set_id, long sem_num)  
 
882
 
883
  Error("SemValue: not implemented", sem_num);
 
884
  return 1L;
 
885
}
 
886
 
 
887
#else
 
888
 
 
889
 
 
890
typedef struct{
 
891
        int state;
 
892
        int pad[15];
 
893
} lock_t;
 
894
static lock_t *locks;
 
895
 
 
896
 
 
897
static char template1[] = "/tmp/SEMA1.XXXXXX";
 
898
static char *filename1 = (char *) NULL;
 
899
static sem_t *sem;
 
900
static lock_t *locks;
 
901
 
 
902
#include <stdio.h>
 
903
 
 
904
long SemSetCreate(long n_sem, long value)
 
905
{
 
906
  int i;
 
907
  shmem_size = MAX_SEMA*sizeof(lock_t);
 
908
 
 
909
  if ( (n_sem <= 0) || (n_sem >= MAX_SEMA) )
 
910
    Error("SemSetCreate: n_sem has invalid value",n_sem);
 
911
 
 
912
  /* allocate shared memory for locks and semaphore val */
 
913
  locks = (lock_t*) mmap((caddr_t)0, shmem_size, PROT_READ|PROT_WRITE,
 
914
                     MAP_ANON|MAP_SHARED, -1, (off_t)0);
 
915
  if(locks == (lock_t*)-1)Error("SemSetCreate: failed to mmap",shmem_size);
 
916
 
 
917
  filename1 = mktemp(template1);
 
918
  sem = sem_open(filename1, O_CREAT|O_EXCL, 0666, 1); 
 
919
  if(!sem)Error("SemSetCreate: failed to sem_open",0);
 
920
  
 
921
  /* initialize locks and semaphore values */
 
922
  bzero(locks,shmem_size);
 
923
  return 1L;
 
924
}
 
925
 
 
926
long SemSetDestroyAll()
 
927
{
 
928
  long status=0;
 
929
  status = munmap((char *) locks, shmem_size);
 
930
  if(status)status = -1;
 
931
  sem_unlink(filename1);
 
932
  return status;
 
933
}
 
934
 
 
935
double __tcgmsg_fred__=0.0;
 
936
void Dummy()
 
937
{
 
938
  int n = 200;                  /* This seems optimal */  
 
939
  while(n--) 
 
940
    __tcgmsg_fred__++;
 
941
}   
 
942
  
 
943
void SemWait(long sem_set_id, long sem_num)
 
944
 
945
  int value = 0, count=0;
 
946
  
 
947
  if ( (sem_num < 0) || (sem_num >= MAX_SEMA) )
 
948
    Error("SemWait: invalid sem_num",sem_num);
 
949
   
 
950
  while (value<=0) {
 
951
    if(sem_wait(sem)<0)Error("SemWait: sem_op error",sem_num);;
 
952
    value = locks[sem_num].state;
 
953
    if (value>0)
 
954
      locks[sem_num].state--;
 
955
    if(sem_post(sem)<0)Error("SemWait: sem_op error",sem_num);;
 
956
    if (value<=0) Dummy();
 
957
    count++;
 
958
    if(count%1000 == 999)usleep(1);
 
959
  }
 
960
 
961
  
 
962
void SemPost(long sem_set_id, long sem_num)
 
963
 
964
  if ( (sem_num < 0) || (sem_num >= MAX_SEMA) )
 
965
    Error("SemPost: invalid sem_num",sem_num); 
 
966
    
 
967
  if(sem_wait(sem)<0)Error("SemPost: sem_op error",sem_num);;
 
968
      locks[sem_num].state++;
 
969
  if(sem_post(sem)<0)Error("SemWait: sem_op error",sem_num);;
 
970
 
971
 
 
972
long SemValue(long sem_set_id, long sem_num)
 
973
 
974
  if ( (sem_num < 0) || (sem_num >= MAX_SEMA) )
 
975
    Error("SemVal: invalid sem_num",sem_num); 
 
976
  return (long)locks[sem_num].state;
 
977
}   
 
978
#endif  
 
979
#endif