]> gcc.gnu.org Git - gcc.git/blame - libstdc++-v3/include/ext/concurrence.h
concurrence.h: Fix __gthread_cond_t initialisation function macro name.
[gcc.git] / libstdc++-v3 / include / ext / concurrence.h
CommitLineData
2e362c74
BK
1// Support for concurrent programing -*- C++ -*-
2
87a20856 3// Copyright (C) 2003, 2004, 2005, 2006, 2007
2e362c74
BK
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library. This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16
17// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING. If not, write to the Free
19// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20// USA.
21
22// As a special exception, you may use this file as part of a free software
23// library without restriction. Specifically, if other files instantiate
24// templates or use macros or inline functions from this file, or you compile
25// this file and link it with other files to produce an executable, this
26// file does not by itself cause the resulting executable to be covered by
27// the GNU General Public License. This exception does not however
28// invalidate any other reasons why the executable file might be covered by
29// the GNU General Public License.
30
31/** @file concurrence.h
32 * This is an internal header file, included by other library headers.
33 * You should not attempt to use it directly.
34 */
35
36#ifndef _CONCURRENCE_H
37#define _CONCURRENCE_H 1
38
f15e02d2 39#include <exception>
2e362c74
BK
40#include <bits/gthr.h>
41#include <bits/functexcept.h>
42
43_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
44
45 // Available locking policies:
46 // _S_single single-threaded code that doesn't need to be locked.
47 // _S_mutex multi-threaded code that requires additional support
ee5ca789 48 // from gthr.h or abstraction layers in concurrence.h.
2e362c74
BK
49 // _S_atomic multi-threaded code using atomic operations.
50 enum _Lock_policy { _S_single, _S_mutex, _S_atomic };
51
52 // Compile time constant that indicates prefered locking policy in
53 // the current configuration.
54 static const _Lock_policy __default_lock_policy =
55#ifdef __GTHREADS
8679a8ef
PC
56#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) \
57 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4))
2e362c74
BK
58 _S_atomic;
59#else
60 _S_mutex;
61#endif
62#else
63 _S_single;
64#endif
8679a8ef 65
f15e02d2
BK
66 // NB: As this is used in libsupc++, need to only depend on
67 // exception. No stdexception classes, no use of std::string.
56acf88c 68 class __concurrence_lock_error : public std::exception
f15e02d2
BK
69 {
70 public:
71 virtual char const*
72 what() const throw()
56acf88c 73 { return "__gnu_cxx::__concurrence_lock_error"; }
f15e02d2
BK
74 };
75
56acf88c 76 class __concurrence_unlock_error : public std::exception
f15e02d2
BK
77 {
78 public:
79 virtual char const*
80 what() const throw()
56acf88c 81 { return "__gnu_cxx::__concurrence_unlock_error"; }
f15e02d2
BK
82 };
83
afd82ef5
DK
84 class __concurrence_broadcast_error : public std::exception
85 {
86 public:
87 virtual char const*
88 what() const throw()
89 { return "__gnu_cxx::__concurrence_broadcast_error"; }
90 };
91
92 class __concurrence_wait_error : public std::exception
93 {
94 public:
95 virtual char const*
96 what() const throw()
97 { return "__gnu_cxx::__concurrence_wait_error"; }
98 };
99
f15e02d2
BK
100 // Substitute for concurrence_error object in the case of -fno-exceptions.
101 inline void
102 __throw_concurrence_lock_error()
103 {
104#if __EXCEPTIONS
56acf88c 105 throw __concurrence_lock_error();
f15e02d2 106#else
87a20856 107 __builtin_abort();
f15e02d2
BK
108#endif
109 }
110
111 inline void
112 __throw_concurrence_unlock_error()
113 {
114#if __EXCEPTIONS
56acf88c 115 throw __concurrence_unlock_error();
f15e02d2 116#else
87a20856 117 __builtin_abort();
f15e02d2
BK
118#endif
119 }
2e362c74 120
afd82ef5
DK
121#ifdef __GTHREAD_HAS_COND
122 inline void
123 __throw_concurrence_broadcast_error()
124 {
125#if __EXCEPTIONS
126 throw __concurrence_broadcast_error();
127#else
128 __builtin_abort();
129#endif
130 }
131
132 inline void
133 __throw_concurrence_wait_error()
134 {
135#if __EXCEPTIONS
136 throw __concurrence_wait_error();
137#else
138 __builtin_abort();
139#endif
140 }
141#endif
142
2e362c74
BK
143 class __mutex
144 {
145 private:
146 __gthread_mutex_t _M_mutex;
147
148 __mutex(const __mutex&);
149 __mutex& operator=(const __mutex&);
150
151 public:
152 __mutex()
153 {
154#if __GTHREADS
155 if (__gthread_active_p())
156 {
157#if defined __GTHREAD_MUTEX_INIT
158 __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT;
159 _M_mutex = __tmp;
160#else
b128c5ef 161 __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
2e362c74
BK
162#endif
163 }
164#endif
165 }
166
167 void lock()
56acf88c 168 {
2e362c74
BK
169#if __GTHREADS
170 if (__gthread_active_p())
171 {
172 if (__gthread_mutex_lock(&_M_mutex) != 0)
f15e02d2 173 __throw_concurrence_lock_error();
2e362c74
BK
174 }
175#endif
176 }
177
178 void unlock()
56acf88c 179 {
2e362c74
BK
180#if __GTHREADS
181 if (__gthread_active_p())
182 {
183 if (__gthread_mutex_unlock(&_M_mutex) != 0)
f15e02d2 184 __throw_concurrence_unlock_error();
2e362c74
BK
185 }
186#endif
187 }
afd82ef5
DK
188
189 __gthread_mutex_t* gthread_mutex(void)
190 { return &_M_mutex; }
2e362c74
BK
191 };
192
193 class __recursive_mutex
194 {
195 private:
196 __gthread_recursive_mutex_t _M_mutex;
197
198 __recursive_mutex(const __recursive_mutex&);
199 __recursive_mutex& operator=(const __recursive_mutex&);
200
201 public:
202 __recursive_mutex()
203 {
204#if __GTHREADS
205 if (__gthread_active_p())
206 {
207#if defined __GTHREAD_RECURSIVE_MUTEX_INIT
208 __gthread_recursive_mutex_t __tmp = __GTHREAD_RECURSIVE_MUTEX_INIT;
209 _M_mutex = __tmp;
210#else
b128c5ef 211 __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
2e362c74
BK
212#endif
213 }
214#endif
215 }
216
217 void lock()
218 {
219#if __GTHREADS
220 if (__gthread_active_p())
221 {
222 if (__gthread_recursive_mutex_lock(&_M_mutex) != 0)
f15e02d2 223 __throw_concurrence_lock_error();
2e362c74
BK
224 }
225#endif
226 }
227
228 void unlock()
229 {
230#if __GTHREADS
231 if (__gthread_active_p())
232 {
233 if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0)
f15e02d2 234 __throw_concurrence_unlock_error();
2e362c74
BK
235 }
236#endif
237 }
afd82ef5
DK
238
239 __gthread_recursive_mutex_t* gthread_recursive_mutex(void)
240 { return &_M_mutex; }
2e362c74
BK
241 };
242
939759fc 243 /// Scoped lock idiom.
2e362c74
BK
244 // Acquire the mutex here with a constructor call, then release with
245 // the destructor call in accordance with RAII style.
246 class __scoped_lock
247 {
248 public:
56acf88c 249 typedef __mutex __mutex_type;
2e362c74
BK
250
251 private:
56acf88c 252 __mutex_type& _M_device;
2e362c74
BK
253
254 __scoped_lock(const __scoped_lock&);
255 __scoped_lock& operator=(const __scoped_lock&);
256
257 public:
56acf88c 258 explicit __scoped_lock(__mutex_type& __name) : _M_device(__name)
2e362c74
BK
259 { _M_device.lock(); }
260
261 ~__scoped_lock() throw()
262 { _M_device.unlock(); }
263 };
264
afd82ef5
DK
265#ifdef __GTHREAD_HAS_COND
266 class __cond
267 {
268 private:
269 __gthread_cond_t _M_cond;
270
271 __cond(const __cond&);
272 __cond& operator=(const __cond&);
273
274 public:
275 __cond()
276 {
277#if __GTHREADS
278 if (__gthread_active_p())
279 {
280#if defined __GTHREAD_COND_INIT
281 __gthread_cond_t __tmp = __GTHREAD_COND_INIT;
282 _M_cond = __tmp;
283#else
f05d0fc1 284 __GTHREAD_COND_INIT_FUNCTION(&_M_cond);
afd82ef5
DK
285#endif
286 }
287#endif
288 }
289
290 void broadcast()
291 {
292#if __GTHREADS
293 if (__gthread_active_p())
294 {
295 if (__gthread_cond_broadcast(&_M_cond) != 0)
296 __throw_concurrence_broadcast_error();
297 }
298#endif
299 }
300
301 void wait(__mutex *mutex)
302 {
303#if __GTHREADS
304 {
305 if (__gthread_cond_wait(&_M_cond, mutex->gthread_mutex()) != 0)
306 __throw_concurrence_wait_error();
307 }
308#endif
309 }
310
311 void wait_recursive(__recursive_mutex *mutex)
312 {
313#if __GTHREADS
314 {
315 if (__gthread_cond_wait_recursive(&_M_cond,
316 mutex->gthread_recursive_mutex())
317 != 0)
318 __throw_concurrence_wait_error();
319 }
320#endif
321 }
322 };
323#endif
324
2e362c74
BK
325_GLIBCXX_END_NAMESPACE
326
327#endif
This page took 0.215979 seconds and 5 git commands to generate.