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 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 
42 namespace 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 
68 public:
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  ///
110  void setLock(
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  ///
176  void broadcast(
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.
pthread_cond_t cond
The low-level condition variable.
void setLock(Lock *l)
set Lock from outside.
void lock()
Acquire this lock. The function sets the internal file/line (debugging) fields to generic values...
Definition: paraPthLock.h:133
~ConditionVariable()
Destroy this condition variable. If the constructor allocated a new Lock for this condition variable ...
ConditionVariable(Lock *l=0)
Create a new condition variable. If l is NULL then the constructor will create a new Lock instance an...
bool ownMutex
This is true iff the constructor did allocate lck.
void broadcast()
Signal on this condition variable. Broadcasting on a condition variable will wake up ALL threads that...
Lock * lck
The lock associated with this instance.
Pthread lock for UG Framework.
void wait()
Wait for this condition variable. The calling thread MUST hold the lock associated with this conditio...
void unlock()
Release the lock associated with this condition variable.
void unlock()
Release this lock.
Definition: paraPthLock.h:161
pthread_mutex_t mtx
The low-level mutex that implements this lock.
Definition: paraPthLock.h:86
Class that implements a lock. The class wraps around pthread_mutex_t and adds some safeguards...
Definition: paraPthLock.h:82
void lock(char const *file, int line)
Acquire the lock associated with this condition variable.
Exception that is thrown whenever something goes wrong with a lock.
Definition: paraPthLock.h:52
void lock()
Acquire the lock associated with this condition variable.
ConditionVariable(ConditionVariable const &)
No copying or assignment of condition variables.
Lock * getLock() const
Get the lock associated with this condition variable.
void signal()
Signal this condition variable. Signalling a condition variable will wake up ONE thread that is curre...
ConditionVariable & operator=(ConditionVariable const &)