Date: Fri, 11 Jun 2004 00:19:11 -0400 (EDT) From: Daniel Eischen <eischen@vigrid.com> To: Sean McNeil <sean@mcneil.com> Cc: freebsd-threads@freebsd.org Subject: Re: signal handler priority issue Message-ID: <Pine.GSO.4.10.10406102337270.18456-100000@pcnet5.pcnet.com> In-Reply-To: <1086924733.65671.81.camel@server.mcneil.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.10.10406102337270.18456-100000>