Rework sleep_setup()/sleep_finish() to no longer hold the scheduler lock
authorclaudio <claudio@openbsd.org>
Tue, 11 Jul 2023 07:02:43 +0000 (07:02 +0000)
committerclaudio <claudio@openbsd.org>
Tue, 11 Jul 2023 07:02:43 +0000 (07:02 +0000)
commitaa563902a9fb835e591cb776b8d405d10f098e06
tree8ac6ca0dec1c0784009326a4c9a1157db10c3bb8
parentb6cae74b6564e00a5f5ef5de5a508134286f3e41
Rework sleep_setup()/sleep_finish() to no longer hold the scheduler lock
between calls.

Instead of forcing an atomic operation across multiple calls use a three
step transaction.
1. setup sleep state by calling sleep_setup()
2. recheck sleep condition to ensure that the event did not fire before
   sleep_setup() registered the proc onto the sleep queue
3. call sleep_finish() to either sleep or keep on running based on the
   step 2 outcome and any possible signal delivery

To make this work wakeup from signals, single thread api and wakeup(9) need
to be aware if a process is between step 1 and step 3 so that the process
is not enqueued back onto the runqueue while going to sleep. Introduce
the p_flag P_WSLEEP to detect this situation.

On top of this remove the spl dance in msleep() which is no longer required.
It is ok to process interrupts between step 1 and 3.

OK mpi@ cheloha@
sys/kern/kern_sched.c
sys/kern/kern_sig.c
sys/kern/kern_synch.c
sys/kern/sched_bsd.c
sys/sys/proc.h