Files
mckernel/test/mng_mod/issues/1029/1029.patch
Masamichi Takagi dbe5e99cf9 Fix test of "make sure to context-switch to idle thread when therad's status is PS_EXITED"
Change-Id: I62ea813656805b6250b0465853e8fa2918b0c86b
Refs: #1029
Refs: #1227
2018-12-04 08:17:54 +00:00

166 lines
4.0 KiB
Diff

diff --git kernel/include/process.h kernel/include/process.h
index 1bf8f27..e55e40e 100644
--- kernel/include/process.h
+++ kernel/include/process.h
@@ -697,6 +697,9 @@ struct thread {
// for performance counter
unsigned long pmc_alloc_map;
unsigned long extra_reg_alloc_map;
+
+// TestCode for #1029
+int started;
};
#define VM_RANGE_CACHE_SIZE 4
diff --git kernel/process.c kernel/process.c
index 3dda3ea..eb65aa9 100644
--- kernel/process.c
+++ kernel/process.c
@@ -3135,12 +3136,16 @@ out_schedule:
schedule();
}
+// TestCode for #1029
+int cases[13] = {0};
void schedule(void)
{
struct cpu_local_var *v;
struct thread *next, *prev, *thread, *tmp = NULL;
int switch_ctx = 0;
struct thread *last;
+// TestCode for #1029
+int runq_cnt = 0, case_num = 0, not_started = 0;
if (cpu_local_var(no_preempt)) {
kprintf("%s: WARNING can't schedule() while no preemption, cnt: %d\n",
@@ -3173,6 +3178,70 @@ redo:
}
}
+// TestCode for #1029
+// flag for thread is started or not
+if (prev) {
+ prev->started = 1;
+}
+
+// check runq
+runq_cnt = 0;
+not_started = 0;
+list_for_each_entry_safe(thread, tmp, &(v->runq), sched_list) {
+ if (thread->tid == prev->tid) {
+ continue;
+ }
+
+ /* Skip not-schedulable */
+ if (thread->status == PS_RUNNING ||
+ (thread->status == PS_INTERRUPTIBLE && hassigpending(thread))) {
+ } else {
+ continue;
+ }
+
+ runq_cnt++;
+ if (!thread->started) {
+ not_started = 1;
+ }
+}
+
+// test cases
+if (!prev) {
+ case_num = 0;
+} else if (prev == &cpu_local_var(idle)) { // prev is idle
+ if (runq_cnt == 0) { // runq is empty
+ case_num = 1;
+ } else if (not_started) { // runq has other NOT_started thread
+ case_num = 2;
+ } else { // runq has other started thread
+ case_num = 3;
+ }
+} else if (v->flags & CPU_FLAG_NEED_MIGRATE) { // prev is NEED_MIGRATE
+ if (runq_cnt == 0) { // runq is empty
+ case_num = 4;
+ } else if (not_started) { // runq has other NOT_started thread
+ case_num = 5;
+ } else { // runq has other started thread
+ case_num = 6;
+ }
+} else if (prev->status != PS_EXITED) { // prev is NOT EXITED
+ if (runq_cnt == 0) { // runq is empty
+ case_num = 7;
+ } else if (not_started) { // runq has other NOT_started thread
+ case_num = 8;
+ } else { // runq has other started thread
+ case_num = 9;
+ }
+} else { // prev is NOT EXITED
+ if (runq_cnt == 0) { // runq is empty
+ case_num = 10;
+ } else if (not_started) { // runq has other NOT_started thread
+ case_num = 11;
+ } else { // runq has other started thread
+ case_num = 12;
+ }
+}
+
/* Switch to idle() when prev is PS_EXITED since it always reaches release_thread()
because it always resumes from just after ihk_mc_switch_context() call. See #1029 */
if (v->flags & CPU_FLAG_NEED_MIGRATE ||
@@ -3208,6 +3269,58 @@ redo:
set_timer();
+// TestCode for #1029
+switch (case_num) {
+case 0:
+ break;
+case 1:
+ if (!cases[case_num]) {
+ if (!switch_ctx) {
+ kprintf("[OK] CT_%03d not_switch\n", case_num);
+ } else {
+ kprintf("[NG] CT_%03d %d -> %d\n", case_num, prev->tid, next->tid);
+ }
+ cases[case_num] = 1;
+ }
+ break;
+case 4:
+case 5:
+case 6:
+case 7:
+case 10:
+case 11:
+case 12:
+ // switch to idle
+ if (!cases[case_num]) {
+ if (next == &cpu_local_var(idle)) {
+ kprintf("[OK] CT_%03d %d => %d\n", case_num,
+ prev ? prev->tid : 0, next ? next->tid : 0);
+ } else {
+ kprintf("[NG] CT_%03d %d => %d\n", case_num, prev->tid, next->tid);
+ }
+ cases[case_num] = 1;
+ }
+ break;
+case 2:
+case 3:
+case 8:
+case 9:
+ // switch to NOT idle
+ if (!cases[case_num]) {
+ if (next != &cpu_local_var(idle)) {
+ kprintf("[OK] CT_%03d %d => %d\n", case_num,
+ prev ? prev->tid : 0, next ? next->tid : 0);
+ } else {
+ kprintf("[NG] CT_%03d\n", case_num);
+ }
+ cases[case_num] = 1;
+ }
+ break;
+
+default:
+ kprintf("unexpected case_num\n");
+}
+
if (switch_ctx) {
dkprintf("schedule: %d => %d \n",
prev ? prev->tid : 0, next ? next->tid : 0);