• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/toolchains/hndtools-arm-linux-2.6.36-uclibc-4.5.3/arm-brcm-linux-uclibcgnueabi/include/c++/4.5.3/ext/
1// Support for concurrent programing -*- C++ -*-
2
3// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009
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 3, 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// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24// <http://www.gnu.org/licenses/>.
25
26/** @file concurrence.h
27 *  This is an internal header file, included by other library headers.
28 *  You should not attempt to use it directly.
29 */
30
31#ifndef _CONCURRENCE_H
32#define _CONCURRENCE_H 1
33
34#include <exception>
35#include <bits/gthr.h>
36#include <bits/functexcept.h>
37
38_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
39
40  // Available locking policies:
41  // _S_single    single-threaded code that doesn't need to be locked.
42  // _S_mutex     multi-threaded code that requires additional support
43  //              from gthr.h or abstraction layers in concurrence.h.
44  // _S_atomic    multi-threaded code using atomic operations.
45  enum _Lock_policy { _S_single, _S_mutex, _S_atomic };
46
47  // Compile time constant that indicates prefered locking policy in
48  // the current configuration.
49  static const _Lock_policy __default_lock_policy =
50#ifdef __GTHREADS
51#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) \
52     && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4))
53  _S_atomic;
54#else
55  _S_mutex;
56#endif
57#else
58  _S_single;
59#endif
60
61  // NB: As this is used in libsupc++, need to only depend on
62  // exception. No stdexception classes, no use of std::string.
63  class __concurrence_lock_error : public std::exception
64  {
65  public:
66    virtual char const*
67    what() const throw()
68    { return "__gnu_cxx::__concurrence_lock_error"; }
69  };
70
71  class __concurrence_unlock_error : public std::exception
72  {
73  public:
74    virtual char const*
75    what() const throw()
76    { return "__gnu_cxx::__concurrence_unlock_error"; }
77  };
78
79  class __concurrence_broadcast_error : public std::exception
80  {
81  public:
82    virtual char const*
83    what() const throw()
84    { return "__gnu_cxx::__concurrence_broadcast_error"; }
85  };
86
87  class __concurrence_wait_error : public std::exception
88  {
89  public:
90    virtual char const*
91    what() const throw()
92    { return "__gnu_cxx::__concurrence_wait_error"; }
93  };
94
95  // Substitute for concurrence_error object in the case of -fno-exceptions.
96  inline void
97  __throw_concurrence_lock_error()
98  {
99#if __EXCEPTIONS
100    throw __concurrence_lock_error();
101#else
102    __builtin_abort();
103#endif
104  }
105
106  inline void
107  __throw_concurrence_unlock_error()
108  {
109#if __EXCEPTIONS
110    throw __concurrence_unlock_error();
111#else
112    __builtin_abort();
113#endif
114  }
115
116#ifdef __GTHREAD_HAS_COND
117  inline void
118  __throw_concurrence_broadcast_error()
119  {
120#if __EXCEPTIONS
121    throw __concurrence_broadcast_error();
122#else
123    __builtin_abort();
124#endif
125  }
126
127  inline void
128  __throw_concurrence_wait_error()
129  {
130#if __EXCEPTIONS
131    throw __concurrence_wait_error();
132#else
133    __builtin_abort();
134#endif
135  }
136#endif
137
138  class __mutex
139  {
140  private:
141    __gthread_mutex_t _M_mutex;
142
143    __mutex(const __mutex&);
144    __mutex& operator=(const __mutex&);
145
146  public:
147    __mutex()
148    {
149#if __GTHREADS
150      if (__gthread_active_p())
151	{
152#if defined __GTHREAD_MUTEX_INIT
153	  __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT;
154	  _M_mutex = __tmp;
155#else
156	  __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
157#endif
158	}
159#endif
160    }
161
162    void lock()
163    {
164#if __GTHREADS
165      if (__gthread_active_p())
166	{
167	  if (__gthread_mutex_lock(&_M_mutex) != 0)
168	    __throw_concurrence_lock_error();
169	}
170#endif
171    }
172
173    void unlock()
174    {
175#if __GTHREADS
176      if (__gthread_active_p())
177	{
178	  if (__gthread_mutex_unlock(&_M_mutex) != 0)
179	    __throw_concurrence_unlock_error();
180	}
181#endif
182    }
183
184    __gthread_mutex_t* gthread_mutex(void)
185      { return &_M_mutex; }
186  };
187
188  class __recursive_mutex
189  {
190  private:
191    __gthread_recursive_mutex_t _M_mutex;
192
193    __recursive_mutex(const __recursive_mutex&);
194    __recursive_mutex& operator=(const __recursive_mutex&);
195
196  public:
197    __recursive_mutex()
198    {
199#if __GTHREADS
200      if (__gthread_active_p())
201	{
202#if defined __GTHREAD_RECURSIVE_MUTEX_INIT
203	  __gthread_recursive_mutex_t __tmp = __GTHREAD_RECURSIVE_MUTEX_INIT;
204	  _M_mutex = __tmp;
205#else
206	  __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
207#endif
208	}
209#endif
210    }
211
212    void lock()
213    {
214#if __GTHREADS
215      if (__gthread_active_p())
216	{
217	  if (__gthread_recursive_mutex_lock(&_M_mutex) != 0)
218	    __throw_concurrence_lock_error();
219	}
220#endif
221    }
222
223    void unlock()
224    {
225#if __GTHREADS
226      if (__gthread_active_p())
227	{
228	  if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0)
229	    __throw_concurrence_unlock_error();
230	}
231#endif
232    }
233
234    __gthread_recursive_mutex_t* gthread_recursive_mutex(void)
235      { return &_M_mutex; }
236  };
237
238  /// Scoped lock idiom.
239  // Acquire the mutex here with a constructor call, then release with
240  // the destructor call in accordance with RAII style.
241  class __scoped_lock
242  {
243  public:
244    typedef __mutex __mutex_type;
245
246  private:
247    __mutex_type& _M_device;
248
249    __scoped_lock(const __scoped_lock&);
250    __scoped_lock& operator=(const __scoped_lock&);
251
252  public:
253    explicit __scoped_lock(__mutex_type& __name) : _M_device(__name)
254    { _M_device.lock(); }
255
256    ~__scoped_lock() throw()
257    { _M_device.unlock(); }
258  };
259
260#ifdef __GTHREAD_HAS_COND
261  class __cond
262  {
263  private:
264    __gthread_cond_t _M_cond;
265
266    __cond(const __cond&);
267    __cond& operator=(const __cond&);
268
269  public:
270    __cond()
271    {
272#if __GTHREADS
273      if (__gthread_active_p())
274	{
275#if defined __GTHREAD_COND_INIT
276	  __gthread_cond_t __tmp = __GTHREAD_COND_INIT;
277	  _M_cond = __tmp;
278#else
279	  __GTHREAD_COND_INIT_FUNCTION(&_M_cond);
280#endif
281	}
282#endif
283    }
284
285    void broadcast()
286    {
287#if __GTHREADS
288      if (__gthread_active_p())
289	{
290	  if (__gthread_cond_broadcast(&_M_cond) != 0)
291	    __throw_concurrence_broadcast_error();
292	}
293#endif
294    }
295
296    void wait(__mutex *mutex)
297    {
298#if __GTHREADS
299      {
300	  if (__gthread_cond_wait(&_M_cond, mutex->gthread_mutex()) != 0)
301	    __throw_concurrence_wait_error();
302      }
303#endif
304    }
305
306    void wait_recursive(__recursive_mutex *mutex)
307    {
308#if __GTHREADS
309      {
310	  if (__gthread_cond_wait_recursive(&_M_cond,
311					    mutex->gthread_recursive_mutex())
312	      != 0)
313	    __throw_concurrence_wait_error();
314      }
315#endif
316    }
317  };
318#endif
319
320_GLIBCXX_END_NAMESPACE
321
322#endif
323