1*38fd1498Szrj // -*- C++ -*- std::terminate, std::unexpected and friends.
2*38fd1498Szrj // Copyright (C) 1994-2018 Free Software Foundation, Inc.
3*38fd1498Szrj //
4*38fd1498Szrj // This file is part of GCC.
5*38fd1498Szrj //
6*38fd1498Szrj // GCC is free software; you can redistribute it and/or modify
7*38fd1498Szrj // it under the terms of the GNU General Public License as published by
8*38fd1498Szrj // the Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj //
11*38fd1498Szrj // GCC is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj //
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj
25*38fd1498Szrj #include "typeinfo"
26*38fd1498Szrj #include "exception"
27*38fd1498Szrj #include <cstdlib>
28*38fd1498Szrj #include "unwind-cxx.h"
29*38fd1498Szrj #include <bits/exception_defines.h>
30*38fd1498Szrj #include <bits/atomic_lockfree_defines.h>
31*38fd1498Szrj
32*38fd1498Szrj #if ATOMIC_POINTER_LOCK_FREE < 2
33*38fd1498Szrj #include <ext/concurrence.h>
34*38fd1498Szrj namespace
35*38fd1498Szrj {
36*38fd1498Szrj __gnu_cxx::__mutex mx;
37*38fd1498Szrj }
38*38fd1498Szrj #endif
39*38fd1498Szrj
40*38fd1498Szrj using namespace __cxxabiv1;
41*38fd1498Szrj
42*38fd1498Szrj void
__terminate(std::terminate_handler handler)43*38fd1498Szrj __cxxabiv1::__terminate (std::terminate_handler handler) throw ()
44*38fd1498Szrj {
45*38fd1498Szrj __try
46*38fd1498Szrj {
47*38fd1498Szrj handler ();
48*38fd1498Szrj std::abort ();
49*38fd1498Szrj }
50*38fd1498Szrj __catch(...)
51*38fd1498Szrj { std::abort (); }
52*38fd1498Szrj }
53*38fd1498Szrj
54*38fd1498Szrj void
terminate()55*38fd1498Szrj std::terminate () throw()
56*38fd1498Szrj {
57*38fd1498Szrj __terminate (get_terminate ());
58*38fd1498Szrj }
59*38fd1498Szrj
60*38fd1498Szrj void
__unexpected(std::unexpected_handler handler)61*38fd1498Szrj __cxxabiv1::__unexpected (std::unexpected_handler handler)
62*38fd1498Szrj {
63*38fd1498Szrj handler();
64*38fd1498Szrj std::terminate ();
65*38fd1498Szrj }
66*38fd1498Szrj
67*38fd1498Szrj void
unexpected()68*38fd1498Szrj std::unexpected ()
69*38fd1498Szrj {
70*38fd1498Szrj __unexpected (get_unexpected ());
71*38fd1498Szrj }
72*38fd1498Szrj
73*38fd1498Szrj std::terminate_handler
set_terminate(std::terminate_handler func)74*38fd1498Szrj std::set_terminate (std::terminate_handler func) throw()
75*38fd1498Szrj {
76*38fd1498Szrj std::terminate_handler old;
77*38fd1498Szrj #if ATOMIC_POINTER_LOCK_FREE > 1
78*38fd1498Szrj __atomic_exchange (&__terminate_handler, &func, &old, __ATOMIC_ACQ_REL);
79*38fd1498Szrj #else
80*38fd1498Szrj __gnu_cxx::__scoped_lock l(mx);
81*38fd1498Szrj old = __terminate_handler;
82*38fd1498Szrj __terminate_handler = func;
83*38fd1498Szrj #endif
84*38fd1498Szrj return old;
85*38fd1498Szrj }
86*38fd1498Szrj
87*38fd1498Szrj std::terminate_handler
get_terminate()88*38fd1498Szrj std::get_terminate () noexcept
89*38fd1498Szrj {
90*38fd1498Szrj std::terminate_handler func;
91*38fd1498Szrj #if ATOMIC_POINTER_LOCK_FREE > 1
92*38fd1498Szrj __atomic_load (&__terminate_handler, &func, __ATOMIC_ACQUIRE);
93*38fd1498Szrj #else
94*38fd1498Szrj __gnu_cxx::__scoped_lock l(mx);
95*38fd1498Szrj func = __terminate_handler;
96*38fd1498Szrj #endif
97*38fd1498Szrj return func;
98*38fd1498Szrj }
99*38fd1498Szrj
100*38fd1498Szrj std::unexpected_handler
set_unexpected(std::unexpected_handler func)101*38fd1498Szrj std::set_unexpected (std::unexpected_handler func) throw()
102*38fd1498Szrj {
103*38fd1498Szrj std::unexpected_handler old;
104*38fd1498Szrj #if ATOMIC_POINTER_LOCK_FREE > 1
105*38fd1498Szrj __atomic_exchange (&__unexpected_handler, &func, &old, __ATOMIC_ACQ_REL);
106*38fd1498Szrj #else
107*38fd1498Szrj __gnu_cxx::__scoped_lock l(mx);
108*38fd1498Szrj old = __unexpected_handler;
109*38fd1498Szrj __unexpected_handler = func;
110*38fd1498Szrj #endif
111*38fd1498Szrj return old;
112*38fd1498Szrj }
113*38fd1498Szrj
114*38fd1498Szrj std::unexpected_handler
get_unexpected()115*38fd1498Szrj std::get_unexpected () noexcept
116*38fd1498Szrj {
117*38fd1498Szrj std::unexpected_handler func;
118*38fd1498Szrj #if ATOMIC_POINTER_LOCK_FREE > 1
119*38fd1498Szrj __atomic_load (&__unexpected_handler, &func, __ATOMIC_ACQUIRE);
120*38fd1498Szrj #else
121*38fd1498Szrj __gnu_cxx::__scoped_lock l(mx);
122*38fd1498Szrj func = __unexpected_handler;
123*38fd1498Szrj #endif
124*38fd1498Szrj return func;
125*38fd1498Szrj }
126