diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2023-07-11 07:02:44 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2023-07-11 07:02:44 +0000 |
commit | 0c9ad61889df5c48a1962e94728a219f5efb362f (patch) | |
tree | b658451f9f4fed0abd3919075a25cbe9763cb9d8 /sys/kern/kern_sched.c | |
parent | 1e529ccf349d7fce1088f9375321b34b5eeda67c (diff) |
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@
Diffstat (limited to 'sys/kern/kern_sched.c')
-rw-r--r-- | sys/kern/kern_sched.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index fe179e4ef64..7fae2f8df33 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sched.c,v 1.77 2023/06/28 08:23:25 claudio Exp $ */ +/* $OpenBSD: kern_sched.c,v 1.78 2023/07/11 07:02:43 claudio Exp $ */ /* * Copyright (c) 2007, 2008 Artur Grabowski <art@openbsd.org> * @@ -248,6 +248,7 @@ setrunqueue(struct cpu_info *ci, struct proc *p, uint8_t prio) KASSERT(ci != NULL); SCHED_ASSERT_LOCKED(); + KASSERT(!ISSET(p->p_flag, P_WSLEEP) || p->p_stat == SSTOP); p->p_cpu = ci; p->p_stat = SRUN; |