Subject: sys_sa_preempt()
To: None <tech-kern@netbsd.org>
From: Bill Stouder-Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 05/22/2007 18:31:53
--dTy3Mrz/UPE2dbVg
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

One obvious thing (Xtos and others have pointed it out) we need to add to=
=20
SA is some way to kick a running thread in the head, so to speak. We need=
=20
to be able to send signals to running threads. With concurrency > 1, it=20
could really be running on another CPU.

My thought was to actually implement sa_preempt(2) and have it deliver an=
=20
SA_UPCALL_USER upcall. Then let libpthread's upcall handling do whatever=20
needs doing. That way if you need to do something in the thread's context=
=20
that shouldn't destroy the thread, you actually have a chance of doing it.=
=20
:-)

Most everything is easy. I just have libpthread track which lwp a given=20
thread is running on (we already track virtual cpu), and then pass that=20
into sa_preempt(2).

The problem I'm emailing about now is how exactly should sys_sa_preempt(),=
=20
which actully implements this, work?

Finding the targeted lwp is easy. Building an upcall event is easy.

Even kicking the other CPU in the head isn't hard, we just need a way to=20
fire off an IPI to it. As I understand it, the interrupt handler will=20
deliver the upcall on its way back to userland.

My question is about the upcall itself.

I'm confused about how exactly I'm supposed to set the "event" and=20
"interrupted" lwps.

In the simple case where thread X is running on lwp Y and I send in the=20
upcall and it gets delivered when Y was running, I think I want both the=20
"event" and "interrupted" lwps to be the same. We still have to do the=20
"You got interrupted who knows when" dance on lwp Y (thread X). But we=20
also want to process signals on the thread on lwp Y (thread X), so it=20
really needs to be the event.

We however have an assert in our kernel upcall enqueue code to say that we=
=20
can't send an upcall where both are the same. Why? Will libpthread=20
explode?



A second issue is that I need some way to tell the upcall delivery code=20
that the "interrupted" thread is whatever is running. A flag that=20
sa_makeupcals notices seems like just the trick.



The astute observer will note that I'm talking about whacking an lwp on=20
the head when I really want to whack a given thread on the head. With=20
concurrency > 1, it is possible that thread X blocks and instead thread Z=
=20
is running on lwp Y by the time the upcall actually gets into userland. I=
=20
think the right way to handle this is for a hook in libpthread to notice a=
=20
defered signal is waiting when it's about to take thread X off of the CPU=
=20
and to instead perform the signal handling right as it starts thread Z.=20
But this is totally a userland issue.

Take care,

Bill

--dTy3Mrz/UPE2dbVg
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (NetBSD)

iD8DBQFGU5mJWz+3JHUci9cRAoGAAJ0cz8ldLFBx/Hv7EAIpQL4capPK2wCgj0H2
/xrvFifRvty9AXdii3nFi4Q=
=PXas
-----END PGP SIGNATURE-----

--dTy3Mrz/UPE2dbVg--