From owner-freebsd-threads@FreeBSD.ORG Fri Jun 11 04:19:18 2004 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6B95116A4CE for ; Fri, 11 Jun 2004 04:19:18 +0000 (GMT) Received: from mail.pcnet.com (mail.pcnet.com [204.213.232.4]) by mx1.FreeBSD.org (Postfix) with ESMTP id 04CB343D49 for ; Fri, 11 Jun 2004 04:19:18 +0000 (GMT) (envelope-from eischen@vigrid.com) Received: from mail.pcnet.com (mail.pcnet.com [204.213.232.4]) by mail.pcnet.com (8.12.10/8.12.1) with ESMTP id i5B4JB6x026465; Fri, 11 Jun 2004 00:19:11 -0400 (EDT) Date: Fri, 11 Jun 2004 00:19:11 -0400 (EDT) From: Daniel Eischen X-Sender: eischen@pcnet5.pcnet.com To: Sean McNeil In-Reply-To: <1086924733.65671.81.camel@server.mcneil.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: freebsd-threads@freebsd.org Subject: Re: signal handler priority issue X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Jun 2004 04:19:18 -0000 On Thu, 10 Jun 2004, Sean McNeil wrote: > I'm working on kse support for gcc/gcj/gij and ran into an interesting > problem with signals: > > Each thread installs a signal handler for synchronization. This signal > handler does a sem_post() to inform it has suspended then goes into a > sigsuspend() loop waiting for a signal that has no handler attached to > it. So we have You might want to look and see how GNAT handles synchronization between tasks; it should be merged into the gcc baseline. > SIGUSR1 - signal handler attached to suspend the thread > SIGUSR2 - no signal handler but waited on in sigsuspend() within the > above handler. Each thread has a signal handler for SIGUSR1? > When you want to have exclusive access, you loop through and stop each ^^^^ suspend? > thread by sending the SIGUSR2 and wait on the semaphore it posts to. ^^^^^^^ SIGUSR1? > Then you do your thing. When done, you signal each thread with SIGUSR2. > The problem I'm seeing is that the signal handler doesn't have > pririority thus it goes to sleep on the sem_post and the SIGUSR2 signal > is lost because it happens before the sigsuspend() is invoked. It doesn't matter. If a signal is sent to a thread (via pthread_kill()) and that signal is masked, then the signal is added to the thread's pending signals. If it hits sigsuspend() at a later point in time and any pending signals are unmasked, then it returns after processing those pending signals. Also, don't confuse kill() with pthread_kill(). If you try to use kill(), it can go to any thread in the process whose signal is unmasked. > I think there is something missing or not functioning in sem_post that > should prevent the signal handler from losing the cpu. I see there is > an enter/exit critical in there. Should that prevent it from context > switching? It would appear not in that exiting a critical section will > cause a yield. A "thread" critical section prevents the thread from getting signals or otherwise interrupted. If the thread blocks on a low-level lock, then it will get swapped out for another thread. > Any help on figuring out how to fix this would be appreciated. Perhaps > someone more familiar with kse can tell me how to go about changing it > so that a signal handler cannot cause a yield. Perhaps something in > _thr_sig_handler? The critical section should prevent the signal handler from being invoked. Put some printf()'s in after the sem_post() and in the signal handler(). The signal handler printf()'s should always occur after the sem_post(). Plus, you shouldn't be getting that signal since it should be masked until sigsuspend() is called. Is it getting past sem_post() and into sigsuspend() or not? If it is getting past sem_post(), then I don't think that is your problem. -- Dan Eischen