~ubuntu-branches/ubuntu/trusty/nwchem/trusty-proposed

« back to all changes in this revision

Viewing changes to src/tools/ga-5-1/armci/examples/benchmarks/lu/pthreads/barrier.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
 
/** @file barrier.c
6
 
 *
7
 
 * This file implements the "barrier" synchronization construct.
8
 
 *
9
 
 * A barrier causes threads to wait until a set of threads has
10
 
 * all "reached" the barrier. The number of threads required is
11
 
 * set when the barrier is initialized, and cannot be changed
12
 
 * except by reinitializing.
13
 
 *
14
 
 * The barrier_init() and barrier_destroy() functions,
15
 
 * respectively, allow you to initialize and destroy the
16
 
 * barrier.
17
 
 *
18
 
 * The barrier_wait() function allows a thread to wait for a
19
 
 * barrier to be completed. One thread (the one that happens to
20
 
 * arrive last) will return from barrier_wait() with the status
21
 
 * -1 on success -- others will return with 0. The special
22
 
 * status makes it easy for the calling code to cause one thread
23
 
 * to do something in a serial region before entering another
24
 
 * parallel section of code.
25
 
 */
26
 
#include <pthread.h>
27
 
 
28
 
#include "errors.h"
29
 
#include "barrier.h"
30
 
 
31
 
/**
32
 
 * Initialize a barrier for use.
33
 
 */
34
 
int barrier_init (barrier_t *barrier, int count)
35
 
{
36
 
    int status;
37
 
 
38
 
    barrier->threshold = barrier->counter = count;
39
 
    barrier->cycle = 0;
40
 
    status = pthread_mutex_init (&barrier->mutex, NULL);
41
 
    if (status != 0)
42
 
        return status;
43
 
    status = pthread_cond_init (&barrier->cv, NULL);
44
 
    if (status != 0) {
45
 
        pthread_mutex_destroy (&barrier->mutex);
46
 
        return status;
47
 
    }
48
 
    barrier->valid = BARRIER_VALID;
49
 
    return 0;
50
 
}
51
 
 
52
 
/**
53
 
 * Destroy a barrier when done using it.
54
 
 */
55
 
int barrier_destroy (barrier_t *barrier)
56
 
{
57
 
    int status, status2;
58
 
 
59
 
    if (barrier->valid != BARRIER_VALID)
60
 
        return EINVAL;
61
 
 
62
 
    status = pthread_mutex_lock (&barrier->mutex);
63
 
    if (status != 0)
64
 
        return status;
65
 
 
66
 
    /*
67
 
     * Check whether any threads are known to be waiting; report
68
 
     * "BUSY" if so.
69
 
     */
70
 
    if (barrier->counter != barrier->threshold) {
71
 
        pthread_mutex_unlock (&barrier->mutex);
72
 
        return EBUSY;
73
 
    }
74
 
 
75
 
    barrier->valid = 0;
76
 
    status = pthread_mutex_unlock (&barrier->mutex);
77
 
    if (status != 0)
78
 
        return status;
79
 
 
80
 
    /*
81
 
     * If unable to destroy either 1003.1c synchronization
82
 
     * object, return the error status.
83
 
     */
84
 
    status = pthread_mutex_destroy (&barrier->mutex);
85
 
    status2 = pthread_cond_destroy (&barrier->cv);
86
 
    return (status == 0 ? status : status2);
87
 
}
88
 
 
89
 
/**
90
 
 * Wait for all members of a barrier to reach the barrier. When
91
 
 * the count (of remaining members) reaches 0, broadcast to wake
92
 
 * all threads waiting.
93
 
 */
94
 
int barrier_wait (barrier_t *barrier)
95
 
{
96
 
    int status, cancel, tmp, cycle;
97
 
 
98
 
    if (barrier->valid != BARRIER_VALID)
99
 
        return EINVAL;
100
 
 
101
 
    status = pthread_mutex_lock (&barrier->mutex);
102
 
    if (status != 0)
103
 
        return status;
104
 
 
105
 
    cycle = barrier->cycle;   /* Remember which cycle we're on */
106
 
 
107
 
    if (--barrier->counter == 0) {
108
 
        barrier->cycle = !barrier->cycle;
109
 
        barrier->counter = barrier->threshold;
110
 
        status = pthread_cond_broadcast (&barrier->cv);
111
 
        /*
112
 
         * The last thread into the barrier will return status
113
 
         * -1 rather than 0, so that it can be used to perform
114
 
         * some special serial code following the barrier.
115
 
         */
116
 
        if (status == 0)
117
 
            status = -1;
118
 
    } else {
119
 
        /*
120
 
         * Wait with cancellation disabled, because barrier_wait
121
 
         * should not be a cancellation point.
122
 
         */
123
 
        pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &cancel);
124
 
 
125
 
        /*
126
 
         * Wait until the barrier's cycle changes, which means
127
 
         * that it has been broadcast, and we don't want to wait
128
 
         * anymore.
129
 
         */
130
 
        while (cycle == barrier->cycle) {
131
 
            status = pthread_cond_wait (
132
 
                    &barrier->cv, &barrier->mutex);
133
 
            if (status != 0) break;
134
 
        }
135
 
 
136
 
        pthread_setcancelstate (cancel, &tmp);
137
 
    }
138
 
    /*
139
 
     * Ignore an error in unlocking. It shouldn't happen, and
140
 
     * reporting it here would be misleading -- the barrier wait
141
 
     * completed, after all, whereas returning, for example,
142
 
     * EINVAL would imply the wait had failed. The next attempt
143
 
     * to use the barrier *will* return an error, or hang, due
144
 
     * to whatever happened to the mutex.
145
 
     */
146
 
    pthread_mutex_unlock (&barrier->mutex);
147
 
    return status;          /* error, -1 for waker, or 0 */
148
 
}