signal handler priority issue
Daniel Eischen
eischen at vigrid.com
Fri Jun 11 04:19:18 GMT 2004
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
More information about the freebsd-threads
mailing list