Skip site navigation (1)Skip section navigation (2)
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>