diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/include/sys/proc.h | 1 | ||||
-rw-r--r-- | sys/kern/kern_sched.c | 24 |
2 files changed, 20 insertions, 5 deletions
diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h index 6318c06..37cf413 100644 --- a/sys/include/sys/proc.h +++ b/sys/include/sys/proc.h @@ -84,6 +84,7 @@ struct proc { #define PROC_LEAFQ BIT(3) /* Leaf queue is active */ #define PROC_WAITED BIT(4) /* Being waited on by parent */ #define PROC_KTD BIT(5) /* Kernel thread */ +#define PROC_SLEEP BIT(6) /* Thread execution paused */ struct proc *this_td(void); struct proc *get_child(struct proc *cur, pid_t pid); diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 65e08d7..c074f75 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -104,12 +104,22 @@ sched_dequeue_td(void) for (size_t i = 0; i < SCHED_NQUEUE; ++i) { queue = &qlist[i]; - if (!TAILQ_EMPTY(&queue->q)) { - td = TAILQ_FIRST(&queue->q); - TAILQ_REMOVE(&queue->q, td, link); - spinlock_release(&tdq_lock); - return td; + if (TAILQ_EMPTY(&queue->q)) { + continue; } + + td = TAILQ_FIRST(&queue->q); + if (td == NULL) { + continue; + } + + TAILQ_REMOVE(&queue->q, td, link); + if (ISSET(td->flags, PROC_SLEEP)) { + continue; + } + + spinlock_release(&tdq_lock); + return td; } /* We got nothing */ @@ -125,6 +135,10 @@ sched_enqueue_td(struct proc *td) { struct sched_queue *queue; + if (ISSET(td->flags, PROC_SLEEP)) { + return; + } + spinlock_acquire(&tdq_lock); queue = &qlist[td->priority]; |