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

« 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, 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
 
/*
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
 
}