aboutsummaryrefslogtreecommitdiff
path: root/gcc/libgcc2.c
diff options
context:
space:
mode:
authorMike Stump <mrs@wrs.com>1998-11-23 20:37:32 +0000
committerJason Merrill <jason@gcc.gnu.org>1998-11-23 15:37:32 -0500
commitd0b9a143e7552eef02291ab94d986867acb828ee (patch)
tree08c5c3cd1e8bdb4d696dd40cbaf8638a9b5cf655 /gcc/libgcc2.c
parent8c8a9717085130efbd17e89ab68aa25bc8e8ef0d (diff)
downloadgcc-d0b9a143e7552eef02291ab94d986867acb828ee.zip
gcc-d0b9a143e7552eef02291ab94d986867acb828ee.tar.gz
gcc-d0b9a143e7552eef02291ab94d986867acb828ee.tar.bz2
libgcc2.c (top_elt): Remove top_elt, it isn't thread safe.
* libgcc2.c (top_elt): Remove top_elt, it isn't thread safe. The strategy we now use is to pre allocate the top_elt along with the EH context so that each thread has its own top_elt. This is necessary as the dynmanic cleanup chain is used on the top element of the stack and each thread MUST have its own. (eh_context_static): Likewise. (new_eh_context): Likewise. (__sjthrow): Likewise. From-SVN: r23818
Diffstat (limited to 'gcc/libgcc2.c')
-rw-r--r--gcc/libgcc2.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 029c624..0b5bfa3 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -3067,10 +3067,6 @@ __empty ()
#include <stdio.h>
#endif
-/* This is a safeguard for dynamic handler chain. */
-
-static void *top_elt[2];
-
/* Allocate and return a new EH context structure. */
extern void __throw ();
@@ -3078,15 +3074,26 @@ extern void __throw ();
static void *
new_eh_context ()
{
- struct eh_context *eh = (struct eh_context *) malloc (sizeof *eh);
- if (! eh)
+ struct eh_full_context {
+ struct eh_context c;
+ void *top_elt[2];
+ } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
+
+ if (! ehfc)
__terminate ();
- memset (eh, 0, sizeof *eh);
+ memset (ehfc, 0, sizeof *ehfc);
- eh->dynamic_handler_chain = top_elt;
+ ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
- return eh;
+ /* This should optimize out entirely. This should always be true,
+ but just in case it ever isn't, don't allow bogus code to be
+ generated. */
+
+ if ((void*)(&ehfc->c) != (void*)ehfc)
+ __terminate ();
+
+ return &ehfc->c;
}
#if __GTHREADS
@@ -3180,6 +3187,8 @@ eh_context_static ()
{
static struct eh_context eh;
static int initialized;
+ static void *top_elt[2];
+
if (! initialized)
{
initialized = 1;
@@ -3290,7 +3299,7 @@ __sjthrow ()
/* We must call terminate if we try and rethrow an exception, when
there is no exception currently active and when there are no
handlers left. */
- if (! eh->info || (*dhc) == top_elt)
+ if (! eh->info || (*dhc)[0] == 0)
__terminate ();
/* Find the jmpbuf associated with the top element of the dynamic