summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/machine/cpu.c2
-rw-r--r--kern/thread.c19
-rw-r--r--kern/thread.h5
3 files changed, 24 insertions, 2 deletions
diff --git a/arch/x86/machine/cpu.c b/arch/x86/machine/cpu.c
index cb7a6a6c..66bc8d9e 100644
--- a/arch/x86/machine/cpu.c
+++ b/arch/x86/machine/cpu.c
@@ -594,7 +594,7 @@ cpu_thread_schedule_intr(struct trap_frame *frame)
lapic_eoi();
- /* Let the return from interrupt code invoke the scheduler */
+ thread_schedule_intr();
}
void
diff --git a/kern/thread.c b/kern/thread.c
index 325c4734..47225641 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -205,6 +205,7 @@ struct thread_runq {
/* Ticks before the next balancing attempt when a run queue is idle */
unsigned int idle_balance_ticks;
+ struct evcnt ev_schedule;
struct evcnt ev_tick;
} __aligned(CPU_L1_SIZE);
@@ -353,6 +354,7 @@ static void __init
thread_runq_init(struct thread_runq *runq, struct thread *booter)
{
char name[EVCNT_NAME_SIZE];
+ unsigned int runq_id;
spinlock_init(&runq->lock);
runq->nr_threads = 0;
@@ -362,7 +364,10 @@ thread_runq_init(struct thread_runq *runq, struct thread *booter)
runq->balancer = NULL;
runq->idler = NULL;
runq->idle_balance_ticks = (unsigned int)-1;
- snprintf(name, sizeof(name), "thread_tick/%u", thread_runq_id(runq));
+ runq_id = thread_runq_id(runq);
+ snprintf(name, sizeof(name), "thread_schedule/%u", runq_id);
+ evcnt_register(&runq->ev_schedule, name);
+ snprintf(name, sizeof(name), "thread_tick/%u", runq_id);
evcnt_register(&runq->ev_tick, name);
}
@@ -1976,6 +1981,18 @@ thread_yield(void)
}
void
+thread_schedule_intr(void)
+{
+ struct thread_runq *runq;
+
+ assert(!cpu_intr_enabled());
+ assert(!thread_preempt_enabled());
+
+ runq = thread_runq_local();
+ evcnt_inc(&runq->ev_schedule);
+}
+
+void
thread_tick(void)
{
struct thread_runq *runq;
diff --git a/kern/thread.h b/kern/thread.h
index 01a2a75b..621e6a14 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -307,6 +307,11 @@ void __noreturn thread_run_scheduler(void);
void thread_yield(void);
/*
+ * Report a scheduling interrupt from a remote processor.
+ */
+void thread_schedule_intr(void);
+
+/*
* Report a periodic timer interrupt on the thread currently running on
* the local processor.
*