summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/machine/trap.c2
-rw-r--r--kern/thread.c18
-rw-r--r--kern/thread.h15
3 files changed, 27 insertions, 8 deletions
diff --git a/arch/x86/machine/trap.c b/arch/x86/machine/trap.c
index 18bff6bc..26656204 100644
--- a/arch/x86/machine/trap.c
+++ b/arch/x86/machine/trap.c
@@ -150,7 +150,7 @@ trap_main(struct trap_frame *frame)
{
assert(frame->vector < ARRAY_SIZE(trap_handlers));
trap_handlers[frame->vector].fn(frame);
- thread_reschedule();
+ thread_intr_schedule();
}
#ifdef __LP64__
diff --git a/kern/thread.c b/kern/thread.c
index dcf038c3..27cdb1b5 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -251,7 +251,7 @@ thread_schedule(void)
}
void
-thread_reschedule(void)
+thread_intr_schedule(void)
{
struct thread_runq *runq;
struct thread *thread;
@@ -267,6 +267,22 @@ thread_reschedule(void)
}
void
+thread_preempt_schedule(void)
+{
+ struct thread_runq *runq;
+ struct thread *thread;
+
+ runq = thread_runq_local();
+ thread = runq->current;
+ assert(thread != NULL);
+
+ if ((thread->preempt == 0)) {
+ assert(!cpu_intr_enabled());
+ thread_schedule();
+ }
+}
+
+void
thread_tick(void)
{
struct thread_runq *runq;
diff --git a/kern/thread.h b/kern/thread.h
index 0022591d..b68b5b38 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -97,11 +97,14 @@ void __noreturn thread_run(void);
void thread_schedule(void);
/*
- * Invoke the scheduler if the current thread is marked for reschedule.
- *
- * Called from interrupt context.
+ * Invoke the scheduler from interrupt context.
+ */
+void thread_intr_schedule(void);
+
+/*
+ * Invoke the scheduler from preemption control functions.
*/
-void thread_reschedule(void);
+void thread_preempt_schedule(void);
/*
* Report a periodic timer interrupt on the thread currently running on
@@ -156,8 +159,8 @@ thread_preempt_enable(void)
assert(thread->preempt != 0);
thread->preempt--;
- if ((thread->preempt == 0) && (thread->flags & THREAD_RESCHEDULE))
- thread_schedule();
+ if (thread->flags & THREAD_RESCHEDULE)
+ thread_preempt_schedule();
}
static inline void