kernel: scheduling fix for ARM
[minix.git] / kernel / arch / earm / arch_clock.c
blob67fc0ed458fe489afaff68593dcd8163886f607b
2 /* ARM-specific clock functions. */
4 #include "kernel/kernel.h"
6 #include "kernel/clock.h"
7 #include "kernel/proc.h"
8 #include "kernel/interrupt.h"
9 #include <minix/u64.h>
10 #include "kernel/glo.h"
11 #include "kernel/profile.h"
14 #include "kernel/spinlock.h"
16 #ifdef CONFIG_SMP
17 #include "kernel/smp.h"
18 #endif
20 #include "omap_timer.h"
21 #include "omap_intr.h"
23 static unsigned tsc_per_ms[CONFIG_MAX_CPUS];
25 int init_local_timer(unsigned freq)
27 omap3_timer_init(freq);
28 omap3_frclock_init();
29 /* always only 1 cpu in the system */
30 tsc_per_ms[0] = 1;
32 return 0;
35 void stop_local_timer(void)
37 omap3_timer_stop();
40 void arch_timer_int_handler(void)
42 omap3_timer_int_handler();
45 void cycles_accounting_init(void)
47 read_tsc_64(get_cpu_var_ptr(cpu, tsc_ctr_switch));
49 make_zero64(get_cpu_var(cpu, cpu_last_tsc));
50 make_zero64(get_cpu_var(cpu, cpu_last_idle));
53 void context_stop(struct proc * p)
55 u64_t tsc;
56 u32_t tsc_delta;
57 u64_t * __tsc_ctr_switch = get_cpulocal_var_ptr(tsc_ctr_switch);
59 read_tsc_64(&tsc);
60 tsc_delta = tsc - *__tsc_ctr_switch;
61 p->p_cycles += tsc_delta;
63 if(kbill_ipc) {
64 kbill_ipc->p_kipc_cycles =
65 add64(kbill_ipc->p_kipc_cycles, tsc_delta);
66 kbill_ipc = NULL;
69 if(kbill_kcall) {
70 kbill_kcall->p_kcall_cycles =
71 add64(kbill_kcall->p_kcall_cycles, tsc_delta);
72 kbill_kcall = NULL;
76 * deduct the just consumed cpu cycles from the cpu time left for this
77 * process during its current quantum. Skip IDLE and other pseudo kernel
78 * tasks
80 if (p->p_endpoint >= 0) {
81 #if DEBUG_RACE
82 p->p_cpu_time_left = 0;
83 #else
84 if (tsc_delta < p->p_cpu_time_left) {
85 p->p_cpu_time_left -= tsc_delta;
86 } else p->p_cpu_time_left = 0;
87 #endif
90 *__tsc_ctr_switch = tsc;
93 void context_stop_idle(void)
95 int is_idle;
96 #ifdef CONFIG_SMP
97 unsigned cpu = cpuid;
98 #endif
100 is_idle = get_cpu_var(cpu, cpu_is_idle);
101 get_cpu_var(cpu, cpu_is_idle) = 0;
103 context_stop(get_cpulocal_var_ptr(idle_proc));
105 if (is_idle)
106 restart_local_timer();
107 #if SPROFILE
108 if (sprofiling)
109 get_cpulocal_var(idle_interrupted) = 1;
110 #endif
113 void restart_local_timer(void)
117 int register_local_timer_handler(const irq_handler_t handler)
119 return omap3_register_timer_handler(handler);
122 u64_t ms_2_cpu_time(unsigned ms)
124 return mul64u(tsc_per_ms[cpuid], ms);
127 unsigned cpu_time_2_ms(u64_t cpu_time)
129 return div64u(cpu_time, tsc_per_ms[cpuid]);
132 short cpu_load(void)
134 return 0;