Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 May 2003 18:11:21 -0700 (PDT)
From:      Julian Elischer <julian@elischer.org>
To:        Peter Wemm <peter@wemm.org>, John Baldwin <jhb@freebsd.org>, threads@freebsd.org
Subject:   Multiplexed threads signals.
Message-ID:  <Pine.BSF.4.21.0305121711350.94099-100000@InterJet.elischer.org>

next in thread | raw e-mail | index | archive | help

I'm looking at trying to work out who is to deliver a signal in an M:N
process. We never answered some of these questions.. Altering ht ecode I
find that I need to answer them now..


This started off as a comment in the code but it kept growing...

better to discuss it...

    /* Here we need to decide our policy
     * with respect to waking up threads for async signal
     * delivery. Generally in this library, async signals are not
     * actually delivered to teh process, but rather a notification is 
     * delivered during an upcall with a mask similar to that 
     * used in the sigpending() call, and the library 'fetches' 
     * the waiting signal using sigwait();

(0) - threads in sigwait for the signal get first crack.

(1)  * Firstly, if we interrupted a thread in userland,
     * don't wake up ANY kernel threads, When we finish 
     * it's going back. It can take the signal with it..
     * SYNC signals take this path, but do not create upcalls.
     * Async signals only do this if there is an upcall possible.

I think that is probably ok..
Only async calls proceed beyond here.

(2)  * Secondly we will look for an idle upcall
     * and make it do an upcall. Better to bring up
     * another upcall than to interrupt a thread that
     * may not deserve being interrupted.

Not really a problem.
 
(3)  * If there is a thread runnable that is going
     * to return to userland upon resumption
     *  (i.e. been pre-empted). Set its bit and
     * let it handle it. Maybe give it a boost
     * if its low priority. If several, choose
     * highest priority. Don't do this if an upcall
     * is not possible, for that thread.
     * An actual upcall thread takes priority.

Existing code will force this to convert to an upcall
on transition to userland.

(4)  * If there is a thread actually running NOW
     * on another CPU and in userland, whack it
     * with an IPI and leave the rest to it.
     * We can not tell if it will create an upcall
     * on getting whacked since we can't look at it's
     * upcall mailbox.

This results in option (1) for the other thread.
But if it's in the UTS, no upcall will result.
If this happens we are left with an un-notified signal, but
at least we know that there will be at least one thread coming down
eventually. if a process decides to run in purely non-upcall mode,
then we can not deliver any async signals to it.. This could be a
problem. This suggests that we need a way to deliver signals without
the complicity of the UTS. Maybe if the next upgoing thread
is not capable of doing an upcall, we just deliver on the stack as per
normal.

     * To some extent
     * this suggests that we look for pending signals
     * when ENTERING the kernel for a syscall. One could
     * make the point that it MIGHT have received a clock
     * interrupt 1 instraction before enterring the syscall,
     * and then continued on to do the syscall.
     * This would be akin to returning an ERESTART
     * but before actually doing the meat of the syscall.

Peter suggested that we keep a per-KSEGRP mask
(lazily set) and that if we encounter a ksegrp with a signal
unmasked and registered as not multiplexing, we just deliver up to it as
on its stack.. (i.e. system scop threads just get signals as per normal)
this coincides with what  libthr does in the degenerate case.

Julian






Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0305121711350.94099-100000>