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

« back to all changes in this revision

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