Scippy

UG

Ubiquity Generator framework

paraPthCondVar.h
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and software framework */
4/* UG --- Ubquity Generator Framework */
5/* */
6/* Copyright Written by Yuji Shinano <shinano@zib.de>, */
7/* Copyright (C) 2021-2024 by Zuse Institute Berlin, */
8/* licensed under LGPL version 3 or later. */
9/* Commercial licenses are available through <licenses@zib.de> */
10/* */
11/* This code is free software; you can redistribute it and/or */
12/* modify it under the terms of the GNU Lesser General Public License */
13/* as published by the Free Software Foundation; either version 3 */
14/* of the License, or (at your option) any later version. */
15/* */
16/* This program is distributed in the hope that it will be useful, */
17/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19/* GNU Lesser General Public License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
23/* */
24/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25
26/**@file paraPthCondVar.h
27 * @brief Pthread condition variable for UG Framework
28 * @author Yuji Shinano
29 *
30 * Many thanks to Daniel Junglas.
31 *
32 */
33
34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35
36#ifndef __PARA_PTH_COND_VAR_H__
37#define __PARA_PTH_COND_VAR_H__
38
39#include <cassert>
40#include "paraPthLock.h"
41
42namespace UG
43{
44
45///
46/// Condition variable.
47///
48/// This class wraps around pthread_cond_t. A condition variable is always
49/// associated with a mutex (which must be held when the condition controlled
50/// by the condition variable is modified). There are two ways to associate
51/// a mutex (an instance of Lock) with a condition variable:
52/// 1. Create the Lock instance and provide a pointer to it to the
53/// ConditionVariable constructor.
54/// 2. Provide a NULL pointer to the ConditionVariable constructor. In that
55/// case the constructor will allocate a new Lock instance (and the
56/// destructor will destroy that lock).
57///
59
60 Lock *lck; ///< The lock associated with this instance.
61 bool ownMutex; ///< This is true iff the constructor did allocate lck.
62 pthread_cond_t cond; ///< The low-level condition variable.
63
64 /// No copying or assignment of condition variables.
67
68public:
69
70 ///
71 /// Create a new condition variable.
72 /// If l is NULL then the constructor will create a new Lock instance and
73 /// will associate this with the newly created condition variable. The Lock
74 /// instance will be destroyed in the destructor.
75 /// If l is not NULL then the constructor will associate the newly created
76 /// condition variable with l (the destructor will _not_ delete l).
77 ///
79 Lock *l = 0
80 )
81 : lck(l),
82 ownMutex(l == 0)
83 {
84 if ( ownMutex )
85 lck = new Lock(); // May throw LockException or std::bad_alloc
86 int const error = pthread_cond_init(&cond, 0);
87 if ( error ) {
88 if ( ownMutex )
89 delete lck;
90 throw LockException(error);
91 }
92 }
93
94 ///
95 /// Destroy this condition variable.
96 /// If the constructor allocated a new Lock for this condition variable
97 /// then this Lock is also destroyed.
98 ///
100 )
101 {
102 pthread_cond_destroy(&cond);
103 if ( ownMutex )
104 delete lck;
105 }
106
107 ///
108 /// set Lock from outside.
109 ///
111 Lock *l ///< lock
112 )
113 {
114 if( ownMutex ) delete lck;
115 lck = l;
116 ownMutex = false;
117 }
118
119 ///
120 /// Acquire the lock associated with this condition variable.
121 ///
122 void lock(
123 )
124 {
125 lck->lock();
126 }
127
128 ///
129 /// Acquire the lock associated with this condition variable.
130 ///
131 void lock(
132 char const *file, ///< file name
133 int line ///< line number
134 )
135 {
136 lck->lock(file, line);
137 }
138
139 ///
140 /// Release the lock associated with this condition variable.
141 ///
142 void unlock() { lck->unlock(); }
143
144 ///
145 /// Wait for this condition variable.
146 /// The calling thread MUST hold the lock associated with this condition
147 /// variable when calling this function.
148 ///
149 void wait(
150 )
151 {
152 int const error = pthread_cond_wait(&cond, &lck->mtx);
153 if ( error )
154 throw LockException(error);
155 }
156
157
158 ///
159 /// Signal this condition variable.
160 /// Signalling a condition variable will wake up ONE thread that is
161 /// currently waiting on the variable.
162 ///
163 void signal(
164 )
165 {
166 int const error = pthread_cond_signal(&cond);
167 if ( error )
168 throw LockException(error);
169 }
170
171 ///
172 /// Signal on this condition variable.
173 /// Broadcasting on a condition variable will wake up ALL threads that are
174 /// currently waiting on the variable.
175 ///
177 )
178 {
179 int const error = pthread_cond_broadcast(&cond);
180 if ( error )
181 throw LockException(error);
182 }
183
184 ///
185 /// Get the lock associated with this condition variable.
186 /// @return lock
187 ///
189 ) const
190 {
191 return lck;
192 }
193
194};
195
196///
197/// Perform exception-safe waiting on a condition variable.
198/// This macro waits on VAR until COND is true.
199///
200#define CONDITIONVARIABLE_WAIT(var,cond) do { \
201 LockRAII raiiwait_((var)->getLock(), __FILE__, __LINE__); \
202 while (!(cond)) \
203 (var)->wait(); \
204 } while (0)
205
206}
207#endif // __PARA_PTH_COND_VAR_H__
Condition variable.
~ConditionVariable()
Destroy this condition variable. If the constructor allocated a new Lock for this condition variable ...
void lock(char const *file, int line)
Acquire the lock associated with this condition variable.
pthread_cond_t cond
The low-level condition variable.
void broadcast()
Signal on this condition variable. Broadcasting on a condition variable will wake up ALL threads that...
void signal()
Signal this condition variable. Signalling a condition variable will wake up ONE thread that is curre...
ConditionVariable(Lock *l=0)
Create a new condition variable. If l is NULL then the constructor will create a new Lock instance an...
Lock * lck
The lock associated with this instance.
void unlock()
Release the lock associated with this condition variable.
void wait()
Wait for this condition variable. The calling thread MUST hold the lock associated with this conditio...
void lock()
Acquire the lock associated with this condition variable.
void setLock(Lock *l)
set Lock from outside.
bool ownMutex
This is true iff the constructor did allocate lck.
ConditionVariable(ConditionVariable const &)
No copying or assignment of condition variables.
ConditionVariable & operator=(ConditionVariable const &)
Lock * getLock() const
Get the lock associated with this condition variable.
Class that implements a lock. The class wraps around pthread_mutex_t and adds some safeguards.
Definition: paraPthLock.h:82
pthread_mutex_t mtx
The low-level mutex that implements this lock.
Definition: paraPthLock.h:86
void unlock()
Release this lock.
Definition: paraPthLock.h:161
void lock()
Acquire this lock. The function sets the internal file/line (debugging) fields to generic values.
Definition: paraPthLock.h:133
Pthread lock for UG Framework.
Exception that is thrown whenever something goes wrong with a lock.
Definition: paraPthLock.h:52