Subversion Repositories Kolibri OS

Rev

Rev 5134 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5134 serge 1
// -*- C++ -*- Manage the thread-local exception globals.
2
// Copyright (C) 2001-2013 Free Software Foundation, Inc.
3
//
4
// This file is part of GCC.
5
//
6
// GCC is free software; you can redistribute it and/or modify
7
// it under the terms of the GNU General Public License as published by
8
// the Free Software Foundation; either version 3, or (at your option)
9
// any later version.
10
//
11
// GCC is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
//
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// .
24
 
25
#include 
26
#include 
27
#include 
28
#include "cxxabi.h"
29
#include "unwind-cxx.h"
30
#include "bits/gthr.h"
31
 
32
#if _GLIBCXX_HOSTED
33
using std::free;
34
using std::malloc;
35
#else
36
// In a freestanding environment, these functions may not be
37
// available -- but for now, we assume that they are.
38
extern "C" void *malloc (std::size_t);
39
extern "C" void free(void *);
40
#endif
41
 
42
using namespace __cxxabiv1;
43
 
44
#if _GLIBCXX_HAVE_TLS
45
 
46
namespace
47
{
48
  abi::__cxa_eh_globals*
49
  get_global() _GLIBCXX_NOTHROW
50
  {
51
    static __thread abi::__cxa_eh_globals global;
52
    return &global;
53
  }
54
} // anonymous namespace
55
 
56
extern "C" __cxa_eh_globals*
57
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
58
{ return get_global(); }
59
 
60
extern "C" __cxa_eh_globals*
61
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
62
{ return get_global(); }
63
 
64
 
65
#else
66
 
67
// Single-threaded fallback buffer.
68
static __cxa_eh_globals eh_globals;
69
 
70
#if __GTHREADS
71
 
72
static void
73
eh_globals_dtor(void* ptr)
74
{
75
  if (ptr)
76
    {
77
      __cxa_eh_globals* g = reinterpret_cast<__cxa_eh_globals*>(ptr);
78
      __cxa_exception* exn = g->caughtExceptions;
79
      __cxa_exception* next;
80
      while (exn)
81
	{
82
	  next = exn->nextException;
83
	  _Unwind_DeleteException(&exn->unwindHeader);
84
	  exn = next;
85
	}
86
      free(ptr);
87
    }
88
}
89
 
90
struct __eh_globals_init
91
{
92
  __gthread_key_t  	_M_key;
93
  bool 			_M_init;
94
 
95
  __eh_globals_init() : _M_init(false)
5963 serge 96
  {
5134 serge 97
    if (__gthread_active_p())
5963 serge 98
      _M_init = __gthread_key_create(&_M_key, eh_globals_dtor) == 0;
5134 serge 99
  }
100
 
101
  ~__eh_globals_init()
102
  {
103
    if (_M_init)
104
      __gthread_key_delete(_M_key);
105
    _M_init = false;
106
  }
107
};
108
 
109
static __eh_globals_init init;
110
 
111
extern "C" __cxa_eh_globals*
112
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
113
{
114
  __cxa_eh_globals* g;
115
  if (init._M_init)
116
    g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
117
  else
118
    g = &eh_globals;
119
  return g;
120
}
121
 
122
extern "C" __cxa_eh_globals*
123
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
124
{
125
  __cxa_eh_globals* g;
126
  if (init._M_init)
127
    {
128
      g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
129
      if (!g)
130
	{
131
	  void* v = malloc(sizeof(__cxa_eh_globals));
132
	  if (v == 0 || __gthread_setspecific(init._M_key, v) != 0)
133
	    std::terminate();
134
	  g = static_cast<__cxa_eh_globals*>(v);
135
	  g->caughtExceptions = 0;
136
	  g->uncaughtExceptions = 0;
137
#ifdef __ARM_EABI_UNWINDER__
138
	  g->propagatingExceptions = 0;
139
#endif
140
	}
141
    }
142
  else
143
    g = &eh_globals;
144
  return g;
145
}
146
 
147
#else
148
 
149
extern "C" __cxa_eh_globals*
150
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
151
{ return &eh_globals; }
152
 
153
extern "C" __cxa_eh_globals*
154
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
155
{ return &eh_globals; }
156
 
157
#endif
158
 
159
#endif