1ac8e35e1Smrg // Exception Handling support header for -*- C++ -*-
2ac8e35e1Smrg 
3*0bfacb9bSmrg // Copyright (C) 2016-2020 Free Software Foundation, Inc.
4ac8e35e1Smrg //
5ac8e35e1Smrg // This file is part of GCC.
6ac8e35e1Smrg //
7ac8e35e1Smrg // GCC is free software; you can redistribute it and/or modify
8ac8e35e1Smrg // it under the terms of the GNU General Public License as published by
9ac8e35e1Smrg // the Free Software Foundation; either version 3, or (at your option)
10ac8e35e1Smrg // any later version.
11ac8e35e1Smrg //
12ac8e35e1Smrg // GCC is distributed in the hope that it will be useful,
13ac8e35e1Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
14ac8e35e1Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15ac8e35e1Smrg // GNU General Public License for more details.
16ac8e35e1Smrg //
17ac8e35e1Smrg // Under Section 7 of GPL version 3, you are granted additional
18ac8e35e1Smrg // permissions described in the GCC Runtime Library Exception, version
19ac8e35e1Smrg // 3.1, as published by the Free Software Foundation.
20ac8e35e1Smrg 
21ac8e35e1Smrg // You should have received a copy of the GNU General Public License and
22ac8e35e1Smrg // a copy of the GCC Runtime Library Exception along with this program;
23ac8e35e1Smrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24ac8e35e1Smrg // <http://www.gnu.org/licenses/>.
25ac8e35e1Smrg 
26ac8e35e1Smrg /** @file eh_atomics.h
27ac8e35e1Smrg  *  This is an internal header file, included by library source files.
28ac8e35e1Smrg  *  Do not attempt to use it directly.
29ac8e35e1Smrg  */
30ac8e35e1Smrg 
31ac8e35e1Smrg #ifndef _EH_ATOMICS_H
32ac8e35e1Smrg #define _EH_ATOMICS_H 1
33ac8e35e1Smrg 
34ac8e35e1Smrg #include <bits/c++config.h>
35ac8e35e1Smrg #include <bits/atomic_word.h>
36ac8e35e1Smrg #include <bits/atomic_lockfree_defines.h>
37ac8e35e1Smrg #if ATOMIC_INT_LOCK_FREE <= 1
38ac8e35e1Smrg # include <ext/atomicity.h>
39ac8e35e1Smrg #endif
40ac8e35e1Smrg 
41ac8e35e1Smrg #pragma GCC visibility push(default)
42ac8e35e1Smrg extern "C++" {
43ac8e35e1Smrg namespace __gnu_cxx
44ac8e35e1Smrg {
45ac8e35e1Smrg   void
46ac8e35e1Smrg   __eh_atomic_inc (_Atomic_word* __count) __attribute__((always_inline));
47ac8e35e1Smrg 
48ac8e35e1Smrg   bool
49ac8e35e1Smrg   __eh_atomic_dec (_Atomic_word* __count) __attribute__((always_inline));
50ac8e35e1Smrg 
51ac8e35e1Smrg   // Increments the count.
52ac8e35e1Smrg   inline void
__eh_atomic_inc(_Atomic_word * __count)53ac8e35e1Smrg   __eh_atomic_inc (_Atomic_word* __count)
54ac8e35e1Smrg   {
55ac8e35e1Smrg #if ATOMIC_INT_LOCK_FREE > 1
56ac8e35e1Smrg     __atomic_add_fetch (__count, 1, __ATOMIC_ACQ_REL);
57ac8e35e1Smrg #else
58ac8e35e1Smrg     _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE (__count);
59ac8e35e1Smrg     __gnu_cxx::__atomic_add_dispatch (__count, 1);
60ac8e35e1Smrg     _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER (__count);
61ac8e35e1Smrg #endif
62ac8e35e1Smrg   }
63ac8e35e1Smrg 
64ac8e35e1Smrg   // Decrements the count and returns true if it reached zero.
65ac8e35e1Smrg   inline bool
__eh_atomic_dec(_Atomic_word * __count)66ac8e35e1Smrg   __eh_atomic_dec (_Atomic_word* __count)
67ac8e35e1Smrg   {
68ac8e35e1Smrg #if ATOMIC_INT_LOCK_FREE > 1
69ac8e35e1Smrg     return __atomic_sub_fetch (__count, 1, __ATOMIC_ACQ_REL) == 0;
70ac8e35e1Smrg #else
71ac8e35e1Smrg     _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE (__count);
72ac8e35e1Smrg     if (__gnu_cxx::__exchange_and_add_dispatch (__count, -1) == 1)
73ac8e35e1Smrg       {
74ac8e35e1Smrg 	_GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER (__count);
75ac8e35e1Smrg 	return true;
76ac8e35e1Smrg       }
77ac8e35e1Smrg     return false;
78ac8e35e1Smrg #endif
79ac8e35e1Smrg   }
80ac8e35e1Smrg } // namespace __gnu_cxx
81ac8e35e1Smrg }
82ac8e35e1Smrg #pragma GCC visibility pop
83ac8e35e1Smrg 
84ac8e35e1Smrg #endif // _EH_ATOMICS_H
85