summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/include/sys/proc.h1
-rw-r--r--sys/kern/kern_sched.c24
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];