From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28201 invoked by alias); 21 Jun 2006 20:58:06 -0000 Received: (qmail 28190 invoked by uid 22791); 21 Jun 2006 20:58:05 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 21 Jun 2006 20:58:02 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k5LKw0Nj032697 for ; Wed, 21 Jun 2006 16:58:00 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k5LKw0m0009425; Wed, 21 Jun 2006 16:58:00 -0400 Received: from [127.0.0.1] (sebastian-int.corp.redhat.com [172.16.52.221]) by pobox.corp.redhat.com (8.12.8/8.12.8) with ESMTP id k5LKvwde024163; Wed, 21 Jun 2006 16:57:59 -0400 Message-ID: <4499B2D5.80207@redhat.com> Date: Wed, 21 Jun 2006 20:58:00 -0000 From: Keith Seitz User-Agent: Thunderbird 1.5.0.4 (X11/20060516) MIME-Version: 1.0 To: Bryce McKinlay CC: Java Patch List Subject: Re: [RFA] Boehm GC support addition for debugging References: <4496CF73.7000507@redhat.com> <449848BF.8070503@redhat.com> <44984B0B.2050205@redhat.com> <44984C65.6070703@redhat.com> In-Reply-To: <44984C65.6070703@redhat.com> Content-Type: multipart/mixed; boundary="------------090307030904060902060107" X-IsSubscribed: yes Mailing-List: contact java-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: java-patches-owner@gcc.gnu.org X-SW-Source: 2006-q2/txt/msg00459.txt.bz2 This is a multi-part message in MIME format. --------------090307030904060902060107 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1050 Bryce McKinlay wrote: > Keith Seitz wrote: >> Hmm. Okay, well, so should I consider the GC patch "approved" _for >> now_ (or at least until it is a problem for me)? > > Yes, it is approved for libgcj trunk. Okay, I have committed this. I made one small change to accommodate the recent _Jv_ThreadDesc_t patch you committed: I've eliminated GC_suspend_self. GC_suspend_thread will check for this case itself. [That saves me from having to do a pthread_self in otherwise generic code.] Thank you for all your help with this. Keith ChangeLog 2006-06-21 Keith Seitz * 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. --------------090307030904060902060107 Content-Type: text/x-patch; name="gc-suspend.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="gc-suspend.patch" Content-length: 3723 Index: include/gc.h =================================================================== --- include/gc.h (revision 114865) +++ include/gc.h (working copy) @@ -1040,4 +1040,14 @@ } /* 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 */ Index: include/private/pthread_support.h =================================================================== --- include/private/pthread_support.h (revision 114865) +++ include/private/pthread_support.h (working copy) @@ -33,6 +33,7 @@ # 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 */ Index: pthread_stop_world.c =================================================================== --- pthread_stop_world.c (revision 114865) +++ pthread_stop_world.c (working copy) @@ -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 @@ 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 @@ /* 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 @@ 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() --------------090307030904060902060107--