~ubuntu-branches/ubuntu/saucy/nwchem/saucy

« back to all changes in this revision

Viewing changes to src/tools/ga-5-1/armci/tcgmsg/ipcv4.0/sema_convex.c

  • Committer: Package Import Robot
  • Author(s): Michael Banck, Michael Banck, Daniel Leidert
  • Date: 2012-02-09 20:02:41 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120209200241-jgk03qfsphal4ug2
Tags: 6.1-1
* New upstream release.

[ Michael Banck ]
* debian/patches/02_makefile_flags.patch: Updated.
* debian/patches/02_makefile_flags.patch: Use internal blas and lapack code.
* debian/patches/02_makefile_flags.patch: Define GCC4 for LINUX and LINUX64
  (Closes: #632611 and LP: #791308).
* debian/control (Build-Depends): Added openssh-client.
* debian/rules (USE_SCALAPACK, SCALAPACK): Removed variables (Closes:
  #654658).
* debian/rules (LIBDIR, USE_MPIF4, ARMCI_NETWORK): New variables.
* debian/TODO: New file.
* debian/control (Build-Depends): Removed libblas-dev, liblapack-dev and
  libscalapack-mpi-dev.
* debian/patches/04_show_testsuite_diff_output.patch: New patch, shows the
  diff output for failed tests.
* debian/patches/series: Adjusted.
* debian/testsuite: Optionally run all tests if "all" is passed as option.
* debian/rules: Run debian/testsuite with "all" if DEB_BUILD_OPTIONS
  contains "checkall".

[ Daniel Leidert ]
* debian/control: Used wrap-and-sort. Added Vcs-Svn and Vcs-Browser fields.
  (Priority): Moved to extra according to policy section 2.5.
  (Standards-Version): Bumped to 3.9.2.
  (Description): Fixed a typo.
* debian/watch: Added.
* debian/patches/03_hurd-i386_define_path_max.patch: Added.
  - Define MAX_PATH if not defines to fix FTBFS on hurd.
* debian/patches/series: Adjusted.

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
/*
 
6
  These routines simplify the interface to semaphores for use in mutual
 
7
  exclusion and queuing. Hopefully I can also make this portable.
 
8
 
 
9
  An external routine Error is assumed which is called upon an error
 
10
  and tidies up by calling SemSetDestroyAll.
 
11
 
 
12
  In most cases errors cause an internal hard failure (by calling Error).
 
13
 
 
14
  1) make an array of n_sem semaphores, returning the id associated
 
15
     with the entire set. All the semaphore values are initialized to value
 
16
     which should be a positve integer (queuing) or 0 (synchronization).
 
17
     The semaphores in the set are indexed from 0 to n_sem-1.
 
18
 
 
19
     long SemSetCreate(long n_sem, long value)
 
20
 
 
21
  2) Decrement and test the value associated with the semaphore specified by 
 
22
     (sem_set_id, sem_num). In effect this:
 
23
 
 
24
     if (value >= 0) {
 
25
        continue execution
 
26
     }
 
27
     else {
 
28
        wait in queue for the semaphore
 
29
     }
 
30
     decrement value
 
31
 
 
32
     void SemWait(long sem_set_id, long sem_num)
 
33
 
 
34
  3) Increment the value associated with the semaphore specified by
 
35
     (sem_set_id, sem_num). If value <= 0 (i.e. there are processes
 
36
     in the queue) this releases the next process.
 
37
 
 
38
     void SemPost(long sem_set_id, long sem_num)
 
39
     
 
40
  4) Return the current value associated with the semaphore sepcified by
 
41
     (sem_set_id, sem_num).
 
42
 
 
43
     long SemValue(long sem_set_id, long sem_num)
 
44
 
 
45
  5) Destroy the set of semaphores. Any other processes that are accessing
 
46
     or try to access the semaphore set should get an error.
 
47
     On the SUN (all system V machines?) the semaphore sets should
 
48
     be destroyed explicitly before the final process exits.
 
49
     0 is returned if OK. -1 implies an error.
 
50
 
 
51
     long SemSetDestroy(long sem_set_id)
 
52
 
 
53
  6) Destroy all the semaphore sets that are known about. This is really
 
54
     meant for an error routine to call to try and tidy up. Though all
 
55
     applications could call it before the last process exits.
 
56
     0 is returned if OK. -1 implies an error.
 
57
 
 
58
     long SemSetDestroyAll()
 
59
*/
 
60
 
 
61
extern void Error();
 
62
 
 
63
#include <stdio.h>
 
64
#include <sys/param.h>
 
65
#include <sys/file.h>
 
66
#include <sys/mman.h>
 
67
#include <sys/types.h>
 
68
 
 
69
#define MAX_SEM_SETS 20
 
70
#define MAX_N_SEM 100
 
71
 
 
72
/* On the convex a semaphore is a structure but on the apollo
 
73
   it is an array which does not need dereferencing.  Use ADDR
 
74
   to generate the address of a semaphore */
 
75
#ifdef APOLLO
 
76
#define ADDR(x) x
 
77
#else
 
78
#define ADDR(x) &x
 
79
#endif
 
80
 
 
81
extern char *mktemp();
 
82
 
 
83
struct sem_set_struct {
 
84
  int n_sem;                    /* no. of semaphores in set */
 
85
  semaphore lock[MAX_N_SEM];    /* locks for changing value */
 
86
  semaphore wait[MAX_N_SEM];    /* locks for queing */
 
87
  int value[MAX_N_SEM];         /* values */
 
88
};
 
89
 
 
90
static int num_sem_set = 0;
 
91
static struct sem_set_struct *sem_sets;
 
92
static int fd = -1;
 
93
static char template[] = "/tmp/SEMA.XXXXXX";
 
94
static char *filename = (char *) NULL;
 
95
 
 
96
void InitSemSets()
 
97
/* Initialise sem_sets and allocate associated shmem region */
 
98
{
 
99
  int i, j;
 
100
  unsigned size = sizeof(struct sem_set_struct) * MAX_SEM_SETS;
 
101
 
 
102
#ifndef APOLLO
 
103
  /* Generate scratch file to identify region ... mustn't do this
 
104
     on the APOLLO */
 
105
 
 
106
  filename = mktemp(template);
 
107
  if ( (fd = open(filename, O_RDWR|O_CREAT, 0666)) < 0 )
 
108
    Error("InitSemSets: failed to open temporary file",0);
 
109
#endif
 
110
 
 
111
  sem_sets = (struct sem_set_struct *) mmap((caddr_t) 0, &size,
 
112
                     PROT_READ|PROT_WRITE,
 
113
                     MAP_ANON|MAP_HASSEMAPHORE|MAP_SHARED, fd, 0);
 
114
 
 
115
#ifdef APOLLO
 
116
  if (sem_sets == (struct sem_set_struct *) 0)
 
117
    Error("InitSemSets: mmap failed", (long) -1);
 
118
#else
 
119
  if (sem_sets == (struct sem_set_struct *) -1)
 
120
    Error("InitSemSets: mmap failed", (long) -1);
 
121
#endif
 
122
 
 
123
  for (i=0; i<MAX_SEM_SETS; i++) {
 
124
    sem_sets[i].n_sem = 0;
 
125
    for (j=0; j<MAX_N_SEM; j++) {
 
126
      mclear(ADDR(sem_sets[i].lock[j]));
 
127
      mclear(ADDR(sem_sets[i].wait[j]));
 
128
      sem_sets[i].value[j] = 0;
 
129
    }
 
130
  }
 
131
}
 
132
 
 
133
long SemSetCreate(n_sem, value)
 
134
     long n_sem;
 
135
     long value;
 
136
{
 
137
  int i;
 
138
 
 
139
  /* Check for errors and initialise data if first entry */
 
140
 
 
141
  if ( (n_sem <= 0) || (n_sem >= MAX_N_SEM) )
 
142
    Error("SemSetCreate: n_sem has invalid value",n_sem);
 
143
 
 
144
  if (num_sem_set == 0)
 
145
    InitSemSets();
 
146
  else if (num_sem_set >= MAX_SEM_SETS)
 
147
    Error("SemSetCreate: Exceeded man no. of semaphore sets",
 
148
          num_sem_set);
 
149
 
 
150
  /* Initialize the values */
 
151
 
 
152
  for (i=0; i<n_sem; i++)
 
153
    sem_sets[num_sem_set].value[i] = value;
 
154
 
 
155
  sem_sets[num_sem_set].n_sem = n_sem;
 
156
 
 
157
  num_sem_set++;
 
158
 
 
159
  return (long) (num_sem_set - 1);
 
160
}
 
161
 
 
162
void SemWait(sem_set_id, sem_num)
 
163
     long sem_set_id;
 
164
     long sem_num;
 
165
{
 
166
  if ( (sem_set_id < 0) || (sem_set_id >= num_sem_set) )
 
167
    Error("SemWait: invalid sem_set_id",sem_set_id);
 
168
  if ( (sem_num < 0) || (sem_num >= sem_sets[sem_set_id].n_sem) )
 
169
    Error("SemWait: invalid semaphore number in set",sem_num);
 
170
 
 
171
  while (1) {
 
172
 
 
173
    /* Get the lock around the whole semaphore */
 
174
 
 
175
    (void) mset(ADDR(sem_sets[sem_set_id].lock[sem_num]), 1);
 
176
 
 
177
    /* If the value is positive fall thru, else wait */
 
178
 
 
179
    if (sem_sets[sem_set_id].value[sem_num] > 0)
 
180
      break;
 
181
    else {
 
182
      (void) mclear(ADDR(sem_sets[sem_set_id].lock[sem_num]));
 
183
      (void) mset(ADDR(sem_sets[sem_set_id].wait[sem_num]), 1);
 
184
    }
 
185
  }
 
186
 
 
187
  /* Are ready to go ... decrement the value and release lock */
 
188
 
 
189
  sem_sets[sem_set_id].value[sem_num]--;
 
190
  (void) mclear(ADDR(sem_sets[sem_set_id].lock[sem_num]));
 
191
 
 
192
}
 
193
 
 
194
void SemPost(sem_set_id, sem_num)
 
195
     long sem_set_id;
 
196
     long sem_num;
 
197
{
 
198
  int i;
 
199
 
 
200
  if ( (sem_set_id < 0) || (sem_set_id >= num_sem_set) )
 
201
    Error("SemPost: invalid sem_set_id",sem_set_id);
 
202
  if ( (sem_num < 0) || (sem_num >= sem_sets[sem_set_id].n_sem) )
 
203
    Error("SemPost: invalid semaphore number in set",sem_num);
 
204
 
 
205
  /* Get the lock around the whole semaphore */
 
206
 
 
207
  (void) mset(ADDR(sem_sets[sem_set_id].lock[sem_num]), 1);
 
208
  
 
209
  /* Read and increment the value. If is now zero wake up
 
210
     up the queue */
 
211
 
 
212
  sem_sets[sem_set_id].value[sem_num]++;
 
213
  i = sem_sets[sem_set_id].value[sem_num];
 
214
 
 
215
  (void) mclear(ADDR(sem_sets[sem_set_id].lock[sem_num]));
 
216
  if (i >= 0)
 
217
    (void) mclear(ADDR(sem_sets[sem_set_id].wait[sem_num]));
 
218
}
 
219
 
 
220
long SemValue(sem_set_id, sem_num)
 
221
     long sem_set_id;
 
222
     long sem_num;
 
223
{
 
224
  int i;
 
225
 
 
226
  if ( (sem_set_id < 0) || (sem_set_id >= num_sem_set) )
 
227
    Error("SemValue: invalid sem_set_id",sem_set_id);
 
228
  if ( (sem_num < 0) || (sem_num >= sem_sets[sem_set_id].n_sem) )
 
229
    Error("SemValue: invalid semaphore number in set",sem_num);
 
230
 
 
231
  /* There seems no point in getting the lock just to read
 
232
     the value and it seems more useful not to (e.g. debugging) */
 
233
 
 
234
  i = sem_sets[sem_set_id].value[sem_num];
 
235
 
 
236
  return (long) (i-1);
 
237
}
 
238
 
 
239
long SemSetDestroy(sem_set_id)
 
240
     long sem_set_id;
 
241
{
 
242
 
 
243
  if ( (sem_set_id < 0) || (sem_set_id >= num_sem_set) )
 
244
    return -1;
 
245
 
 
246
  sem_sets[sem_set_id].n_sem = 0;
 
247
 
 
248
  return (long) 0;
 
249
}
 
250
  
 
251
long SemSetDestroyAll()
 
252
{
 
253
  long i, status=0;
 
254
 
 
255
  for (i=0; i<num_sem_set; i++)
 
256
    if (sem_sets[i].n_sem)
 
257
      status += SemSetDestroy(i);
 
258
 
 
259
  if (fd >= 0) {
 
260
    (void) close(fd);
 
261
    fd = -1;
 
262
    (void) unlink(filename);
 
263
  }
 
264
 
 
265
  status += munmap((char *) sem_sets, 0);
 
266
 
 
267
  if (status)
 
268
    status = -1;
 
269
 
 
270
  return status;
 
271
}