OpenBSD/sgi on octane2 - clock.cのMP対応
clock.cではクロックの管理にグローバル変数を使ってしまっている。
クロック割り込みは両側のCPUで起き独立で処理したいので、struct cpu_infoへそれらの変数を移動した。
Cで変数の移動するだけだから簡単。
Index: ../include/cpu.h =================================================================== --- ../include/cpu.h (リビジョン 366) +++ ../include/cpu.h (作業コピー) @@ -403,6 +403,10 @@ int ci_want_resched; /* resched() was called */ intrmask_t ci_cpl; intrmask_t ci_ipending; + int ci_clock_started; + u_int32_t ci_cpu_counter_last; + u_int32_t ci_cpu_counter_interval; + u_int32_t ci_pendingticks; }; #define CPUF_PRIMARY 0x01 /* CPU is primary CPU */ Index: clock.c =================================================================== --- clock.c (リビジョン 361) +++ clock.c (作業コピー) @@ -54,11 +54,6 @@ intrmask_t clock_int5(intrmask_t, struct trap_frame *); -int clock_started; -u_int32_t cpu_counter_last; -u_int32_t cpu_counter_interval; -u_int32_t pendingticks; - u_int cp0_get_timecount(struct timecounter *); struct timecounter cp0_timecounter = { @@ -122,6 +117,7 @@ intrmask_t clock_int5(intrmask_t mask, struct trap_frame *tf) { + struct cpu_info *ci = curcpu(); u_int32_t clkdiff; /* @@ -129,7 +125,7 @@ * retrigger it as far as possible. cpu_initclocks() will * take care of retriggering it correctly. */ - if (clock_started == 0) { + if (ci->ci_clock_started == 0) { cp0_set_compare(cp0_get_count() - 1); return CR_INT_5; } @@ -137,35 +133,35 @@ /* * Count how many ticks have passed since the last clock interrupt... */ - clkdiff = cp0_get_count() - cpu_counter_last; - while (clkdiff >= cpu_counter_interval) { - cpu_counter_last += cpu_counter_interval; - clkdiff = cp0_get_count() - cpu_counter_last; - pendingticks++; + clkdiff = cp0_get_count() - ci->ci_cpu_counter_last; + while (clkdiff >= ci->ci_cpu_counter_interval) { + ci->ci_cpu_counter_last += ci->ci_cpu_counter_interval; + clkdiff = cp0_get_count() - ci->ci_cpu_counter_last; + ci->ci_pendingticks++; } - pendingticks++; - cpu_counter_last += cpu_counter_interval; + ci->ci_pendingticks++; + ci->ci_cpu_counter_last += ci->ci_cpu_counter_interval; /* * Set up next tick, and check if it has just been hit; in this * case count it and schedule one tick ahead. */ - cp0_set_compare(cpu_counter_last); - clkdiff = cp0_get_count() - cpu_counter_last; + cp0_set_compare(ci->ci_cpu_counter_last); + clkdiff = cp0_get_count() - ci->ci_cpu_counter_last; if ((int)clkdiff >= 0) { - cpu_counter_last += cpu_counter_interval; - pendingticks++; - cp0_set_compare(cpu_counter_last); + ci->ci_cpu_counter_last += ci->ci_cpu_counter_interval; + ci->ci_pendingticks++; + cp0_set_compare(ci->ci_cpu_counter_last); } /* * Process clock interrupt unless it is currently masked. */ if ((tf->cpl & SPL_CLOCKMASK) == 0) { - while (pendingticks) { + while (ci->ci_pendingticks) { clk_count.ec_count++; hardclock(tf); - pendingticks--; + ci->ci_pendingticks--; } } @@ -203,6 +199,7 @@ void cpu_initclocks() { + struct cpu_info *ci = curcpu(); struct tod_desc *cd = &sys_tod; struct tod_time ct; u_int first_cp0, second_cp0, cycles_per_sec; @@ -244,10 +241,10 @@ /* Start the clock. */ s = splclock(); - cpu_counter_interval = cp0_timecounter.tc_frequency / hz; - cpu_counter_last = cp0_get_count() + cpu_counter_interval; - cp0_set_compare(cpu_counter_last); - clock_started++; + ci->ci_cpu_counter_interval = cp0_timecounter.tc_frequency / hz; + ci->ci_cpu_counter_last = cp0_get_count() + ci->ci_cpu_counter_interval; + cp0_set_compare(ci->ci_cpu_counter_last); + ci->ci_clock_started++; splx(s); }