Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4383 Serge 1
// -*- C++ -*- Manage the thread-local exception globals.
2
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2011
3
// Free Software Foundation, Inc.
4
//
5
// This file is part of GCC.
6
//
7
// GCC is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 3, or (at your option)
10
// any later version.
11
//
12
// GCC 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
// .
25
 
26
#include 
27
#include 
28
#include 
29
#include "cxxabi.h"
30
#include "unwind-cxx.h"
31
#include "bits/gthr.h"
32
 
33
#if _GLIBCXX_HOSTED
34
using std::free;
35
using std::malloc;
36
#else
37
// In a freestanding environment, these functions may not be
38
// available -- but for now, we assume that they are.
39
extern "C" void *malloc (std::size_t);
40
extern "C" void free(void *);
41
#endif
42
 
43
using namespace __cxxabiv1;
44
 
45
#if _GLIBCXX_HAVE_TLS
46
 
47
namespace
48
{
49
  abi::__cxa_eh_globals*
50
  get_global() _GLIBCXX_NOTHROW
51
  {
52
    static __thread abi::__cxa_eh_globals global;
53
    return &global;
54
  }
55
} // anonymous namespace
56
 
57
extern "C" __cxa_eh_globals*
58
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
59
{ return get_global(); }
60
 
61
extern "C" __cxa_eh_globals*
62
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
63
{ return get_global(); }
64
 
65
 
66
#else
67
 
68
// Single-threaded fallback buffer.
69
static __cxa_eh_globals eh_globals;
70
 
71
#if __GTHREADS
72
 
73
static void
74
eh_globals_dtor(void* ptr)
75
{
76
  if (ptr)
77
    {
78
      __cxa_eh_globals* g = reinterpret_cast<__cxa_eh_globals*>(ptr);
79
      __cxa_exception* exn = g->caughtExceptions;
80
      __cxa_exception* next;
81
      while (exn)
82
	{
83
	  next = exn->nextException;
84
	  _Unwind_DeleteException(&exn->unwindHeader);
85
	  exn = next;
86
	}
87
      free(ptr);
88
    }
89
}
90
 
91
struct __eh_globals_init
92
{
93
  __gthread_key_t  	_M_key;
94
  bool 			_M_init;
95
 
96
  __eh_globals_init() : _M_init(false)
97
  {
98
    if (__gthread_active_p())
99
      _M_init = __gthread_key_create(&_M_key, eh_globals_dtor) == 0;
100
  }
101
 
102
  ~__eh_globals_init()
103
  {
104
    if (_M_init)
105
      __gthread_key_delete(_M_key);
106
    _M_init = false;
107
  }
108
};
109
 
110
static __eh_globals_init init;
111
 
112
extern "C" __cxa_eh_globals*
113
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
114
{
115
  __cxa_eh_globals* g;
116
  if (init._M_init)
117
    g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
118
  else
119
    g = &eh_globals;
120
  return g;
121
}
122
 
123
extern "C" __cxa_eh_globals*
124
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
125
{
126
  __cxa_eh_globals* g;
127
  if (init._M_init)
128
    {
129
      g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
130
      if (!g)
131
	{
132
	  void* v = malloc(sizeof(__cxa_eh_globals));
133
	  if (v == 0 || __gthread_setspecific(init._M_key, v) != 0)
134
	    std::terminate();
135
	  g = static_cast<__cxa_eh_globals*>(v);
136
	  g->caughtExceptions = 0;
137
	  g->uncaughtExceptions = 0;
138
#ifdef __ARM_EABI_UNWINDER__
139
	  g->propagatingExceptions = 0;
140
#endif
141
	}
142
    }
143
  else
144
    g = &eh_globals;
145
  return g;
146
}
147
 
148
#else
149
 
150
extern "C" __cxa_eh_globals*
151
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
152
{ return &eh_globals; }
153
 
154
extern "C" __cxa_eh_globals*
155
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
156
{ return &eh_globals; }
157
 
158
#endif
159
 
160
#endif