diff options
author | ivmai <ivmai> | 2010-07-28 20:49:53 +0000 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2011-07-26 21:06:54 +0400 |
commit | 579101b336989280122a2bf4c9a71a43231fbd8a (patch) | |
tree | d19de46b4532115e84cc3c718b8e27a117a7f7ab /pthread_start.c | |
parent | 7af378266a80aa2c83f7319158020088bb13c7fe (diff) | |
download | bdwgc-579101b336989280122a2bf4c9a71a43231fbd8a.tar.gz |
2010-07-29 Ivan Maidanski <ivmai@mail.ru> (with input from NIIBE Yutaka)
* pthread_start.c: New file.
* CMakeLists.txt (SRC): Add pthread_start.c.
* Makefile.am (libgc_la_SOURCES): Ditto.
* Makefile.direct (CSRCS): Ditto.
* Makefile.direct (OBJS): Add pthread_start.obj.
* extra/gc.c: Add a comment; include pthread_start.c.
* pthread_support.c (start_info): Move the struct definition down
closer to its usage.
* pthread_support.c (GC_thread_exit_proc): Replace STATIC with
GC_INNER.
* pthread_support.c (GC_inner_start_routine): Move to the
definition to pthread_start.c; leave only the prototype; remove
STATIC.
* pthread_support.c (GC_start_rtn_prepare_thread): New function
(contains parts of the original GC_inner_start_routine).
* Makefile.in: Regenerate.
* configure: Ditto.
Diffstat (limited to 'pthread_start.c')
-rw-r--r-- | pthread_start.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/pthread_start.c b/pthread_start.c new file mode 100644 index 00000000..a6e1f72d --- /dev/null +++ b/pthread_start.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1994 by Xerox Corporation. All rights reserved. + * Copyright (c) 1996 by Silicon Graphics. All rights reserved. + * Copyright (c) 1998 by Fergus Henderson. All rights reserved. + * Copyright (c) 2000-2010 by Hewlett-Packard Development Company. + * All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + */ + +/* We want to make sure that GC_thread_exit_proc() is unconditionally */ +/* invoked, even if the client is not compiled with -fexceptions, but */ +/* the GC is. The workaround is to put GC_inner_start_routine() in its */ +/* own file (pthread_start.c), and undefine __EXCEPTIONS in the GCC */ +/* case at the top of the file. FIXME: it's still unclear whether this */ +/* will actually cause the exit handler to be invoked last when */ +/* thread_exit is called (and if -fexceptions is used). */ +#if defined(__GNUC__) && defined(__linux__) + /* We undefine __EXCEPTIONS to avoid using GCC __cleanup__ attribute. */ + /* The current NPTL implementation of pthread_cleanup_push uses */ + /* __cleanup__ attribute when __EXCEPTIONS is defined (-fexceptions). */ + /* The stack unwinding and cleanup with __cleanup__ attributes work */ + /* correctly when everything is compiled with -fexceptions, but it is */ + /* not the requirement for this library clients to use -fexceptions */ + /* everywhere. With __EXCEPTIONS undefined, the cleanup routines are */ + /* registered with __pthread_register_cancel thus should work anyway. */ +# undef __EXCEPTIONS +#endif + +#include "private/pthread_support.h" + +#if defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS) + +#include <pthread.h> +#include <sched.h> + +GC_INNER void * GC_start_rtn_prepare_thread(void *(**pstart)(void *), + void **pstart_arg, + struct GC_stack_base *sb, void *arg); +GC_INNER void GC_thread_exit_proc(void *arg); + /* defined in pthread_support.c */ + +/* Invoked from GC_start_routine(). */ +void * GC_CALLBACK GC_inner_start_routine(struct GC_stack_base *sb, void *arg) +{ + void * (*start)(void *); + void * start_arg; + void * result; + GC_thread me = GC_start_rtn_prepare_thread(&start, &start_arg, sb, arg); + + pthread_cleanup_push(GC_thread_exit_proc, 0); + result = (*start)(start_arg); +# ifdef DEBUG_THREADS + GC_printf("Finishing thread 0x%x\n", (unsigned)pthread_self()); +# endif + me -> status = result; + pthread_cleanup_pop(1); + /* Cleanup acquires lock, ensuring that we can't exit while */ + /* a collection that thinks we're alive is trying to stop us. */ + return result; +} + +#endif /* GC_PTHREADS */ |