pthread_stop_world.c (GC_suspend_handler): Redirect to suspension routine if signal is received and thread is flagged...
* pthread_stop_world.c (GC_suspend_handler): Redirect to suspension routine if signal is received and thread is flagged SUSPENDED. (suspend_self): New function. (GC_suspend_thread): New function. (GC_resume_thread): New function. * include/gc.h (GC_suspend_thread): Declare. (GC_resumet_thread): Declare. * include/private/pthread_support.h (SUSPENDED): New GC_thread flag. From-SVN: r114869
This commit is contained in:
parent
c3238e32eb
commit
7691d0d3c9
@ -1,3 +1,15 @@
|
||||
2006-06-21 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* pthread_stop_world.c (GC_suspend_handler): Redirect to suspension
|
||||
routine if signal is received and thread is flagged SUSPENDED.
|
||||
(suspend_self): New function.
|
||||
(GC_suspend_thread): New function.
|
||||
(GC_resume_thread): New function.
|
||||
* include/gc.h (GC_suspend_thread): Declare.
|
||||
(GC_resumet_thread): Declare.
|
||||
* include/private/pthread_support.h (SUSPENDED): New GC_thread
|
||||
flag.
|
||||
|
||||
2006-06-20 Ranjit Mathew <rmathew@gcc.gnu.org>
|
||||
|
||||
Backport Windows 9x/ME VirtualQuery() fix from GC 6.7.
|
||||
|
@ -1040,4 +1040,14 @@ GC_API void GC_register_has_static_roots_callback
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
/* External thread suspension support. These functions do not implement
|
||||
* suspension counts or any other higher-level abstraction. Threads which
|
||||
* have been suspended numerous times will resume with the very first call
|
||||
* to GC_resume_thread.
|
||||
*/
|
||||
#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
|
||||
&& !defined(GC_WIN32_THREADS) && !defined(GC_DARWIN_THREADS)
|
||||
GC_API void GC_suspend_thread GC_PROTO((pthread_t));
|
||||
GC_API void GC_resume_thread GC_PROTO((pthread_t));
|
||||
#endif
|
||||
#endif /* _GC_H */
|
||||
|
@ -33,6 +33,7 @@ typedef struct GC_Thread_Rep {
|
||||
# define FINISHED 1 /* Thread has exited. */
|
||||
# define DETACHED 2 /* Thread is intended to be detached. */
|
||||
# define MAIN_THREAD 4 /* True for the original thread only. */
|
||||
# define SUSPENDED 8 /* True if thread was suspended externally */
|
||||
short thread_blocked; /* Protected by GC lock. */
|
||||
/* Treated as a boolean value. If set, */
|
||||
/* thread will acquire GC lock before */
|
||||
|
@ -13,6 +13,8 @@
|
||||
/* Doesn't exist on HP/UX 11.11. */
|
||||
#endif
|
||||
|
||||
void suspend_self();
|
||||
|
||||
#if DEBUG_THREADS
|
||||
|
||||
#ifndef NSIG
|
||||
@ -127,9 +129,14 @@ extern void GC_with_callee_saves_pushed();
|
||||
|
||||
void GC_suspend_handler(int sig)
|
||||
{
|
||||
int old_errno = errno;
|
||||
GC_with_callee_saves_pushed(GC_suspend_handler_inner, (ptr_t)(word)sig);
|
||||
errno = old_errno;
|
||||
GC_thread me = GC_lookup_thread (pthread_self());
|
||||
if (me -> flags & SUSPENDED)
|
||||
suspend_self();
|
||||
else {
|
||||
int old_errno = errno;
|
||||
GC_with_callee_saves_pushed(GC_suspend_handler_inner, (ptr_t)(word)sig);
|
||||
errno = old_errno;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
@ -137,9 +144,14 @@ void GC_suspend_handler(int sig)
|
||||
/* in the signal handler frame. */
|
||||
void GC_suspend_handler(int sig)
|
||||
{
|
||||
int old_errno = errno;
|
||||
GC_suspend_handler_inner((ptr_t)(word)sig);
|
||||
errno = old_errno;
|
||||
GC_thread me = GC_lookup_thread(pthread_self());
|
||||
if (me -> flags & SUSPENDED)
|
||||
suspend_self();
|
||||
else {
|
||||
int old_errno = errno;
|
||||
GC_suspend_handler_inner((ptr_t)(word)sig);
|
||||
errno = old_errno;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -430,6 +442,47 @@ void GC_stop_world()
|
||||
GC_stopping_thread = 0; /* debugging only */
|
||||
}
|
||||
|
||||
void suspend_self() {
|
||||
GC_thread me = GC_lookup_thread(pthread_self());
|
||||
if (me == NULL)
|
||||
ABORT("attempting to suspend unknown thread");
|
||||
|
||||
me -> flags |= SUSPENDED;
|
||||
GC_start_blocking();
|
||||
while (me -> flags & SUSPENDED)
|
||||
GC_brief_async_signal_safe_sleep();
|
||||
GC_end_blocking();
|
||||
}
|
||||
|
||||
void GC_suspend_thread(pthread_t thread) {
|
||||
if (thread == pthread_self())
|
||||
suspend_self();
|
||||
else {
|
||||
int result;
|
||||
GC_thread t = GC_lookup_thread(thread);
|
||||
if (t == NULL)
|
||||
ABORT("attempting to suspend unknown thread");
|
||||
|
||||
t -> flags |= SUSPENDED;
|
||||
result = pthread_kill (t -> id, SIG_SUSPEND);
|
||||
switch (result) {
|
||||
case ESRCH:
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
ABORT("pthread_kill failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GC_resume_thread(pthread_t thread) {
|
||||
GC_thread t = GC_lookup_thread(thread);
|
||||
if (t == NULL)
|
||||
ABORT("attempting to resume unknown thread");
|
||||
|
||||
t -> flags &= ~SUSPENDED;
|
||||
}
|
||||
|
||||
/* Caller holds allocation lock, and has held it continuously since */
|
||||
/* the world stopped. */
|
||||
void GC_start_world()
|
||||
|
Loading…
Reference in New Issue
Block a user