]> Zhao Yanbai Git Server - minix.git/commitdiff
kernel: scheduling fix for ARM 89/289/2
authorBen Gras <ben@minix3.org>
Sun, 3 Feb 2013 18:28:24 +0000 (19:28 +0100)
committerBen Gras <ben@minix3.org>
Sun, 3 Feb 2013 21:49:05 +0000 (22:49 +0100)
. make read_tsc_64 use the free-running clock, significantly
  improving scheduling behaviour

Change-Id: Idf6a12f6e26be7fe3b3664c278cae846d8b2a442

kernel/arch/earm/arch_clock.c
kernel/arch/earm/memory.c
kernel/arch/earm/omap_timer.c

index 96d8811b2903c076dd9b5b934bacbc54fcb64774..67fc0ed458fe489afaff68593dcd8163886f607b 100644 (file)
@@ -52,13 +52,13 @@ void cycles_accounting_init(void)
 
 void context_stop(struct proc * p)
 {
-       u64_t tsc, tsc_delta;
+       u64_t tsc;
+       u32_t tsc_delta;
        u64_t * __tsc_ctr_switch = get_cpulocal_var_ptr(tsc_ctr_switch);
 
        read_tsc_64(&tsc);
-       p->p_cycles = add64(p->p_cycles, sub64(tsc, *__tsc_ctr_switch));
-
-       tsc_delta = sub64(tsc, *__tsc_ctr_switch);
+       tsc_delta = tsc - *__tsc_ctr_switch;
+       p->p_cycles += tsc_delta;
 
        if(kbill_ipc) {
                kbill_ipc->p_kipc_cycles =
@@ -79,18 +79,11 @@ void context_stop(struct proc * p)
         */
        if (p->p_endpoint >= 0) {
 #if DEBUG_RACE
-               make_zero64(p->p_cpu_time_left);
+               p->p_cpu_time_left = 0;
 #else
-               /* if (tsc_delta < p->p_cpu_time_left) in 64bit */
-               if (ex64hi(tsc_delta) < ex64hi(p->p_cpu_time_left) ||
-                               (ex64hi(tsc_delta) == ex64hi(p->p_cpu_time_left) &&
-                                ex64lo(tsc_delta) < ex64lo(p->p_cpu_time_left)))
-               {
-                       p->p_cpu_time_left = sub64(p->p_cpu_time_left, tsc_delta);
-               }
-               else {
-                       make_zero64(p->p_cpu_time_left);
-               }
+               if (tsc_delta < p->p_cpu_time_left) {
+                       p->p_cpu_time_left -= tsc_delta;
+               } else p->p_cpu_time_left = 0;
 #endif
        }
 
index f422d43be2d2e0e16a46a209744fb58efa8f54d7..9608868a83efdbe59a7e538178f1486e4ea80d54 100644 (file)
@@ -29,6 +29,8 @@ static int freepdes[MAXFREEPDES];
 
 static u32_t phys_get32(phys_bytes v);
 
+extern vir_bytes omap3_gptimer10_base = OMAP3_GPTIMER10_BASE;
+
 void mem_clear_mapcache(void)
 {
        int i;
@@ -763,7 +765,7 @@ int arch_phys_map_reply(const int index, const vir_bytes addr)
                return OK;
        }
        else if (index == frclock_index) {
-               minix_kerninfo.minix_frclock = addr;
+               omap3_gptimer10_base = minix_kerninfo.minix_frclock = addr;
                return OK;
        }
 
index a5bac65a9fef0f19883351e1b021f9a1729ed8f9..cc7dbb402d986d37e516ac5651d0d4b61a0aeb75 100644 (file)
@@ -8,7 +8,9 @@
 #include "omap_intr.h"
 
 static irq_hook_t omap3_timer_hook;            /* interrupt handler hook */
-static u64_t tsc;
+static u64_t high_frc;
+
+vir_bytes omap3_gptimer10_base;
 
 int omap3_register_timer_handler(const irq_handler_t handler)
 {
@@ -90,6 +92,23 @@ void omap3_timer_stop()
     mmio_clear(OMAP3_GPTIMER1_TCLR, OMAP3_TCLR_ST);
 }
 
+static u32_t read_frc(void)
+{
+       u32_t frc = *(u32_t *) ((char *) omap3_gptimer10_base + OMAP3_TCRR);
+       return frc;
+}
+
+static void frc_overflow_check(void)
+{
+       static int prev_frc_valid;
+       static u32_t prev_frc;
+       u32_t cur_frc = read_frc();
+       if(prev_frc_valid && prev_frc > cur_frc)
+               high_frc++;
+       prev_frc = cur_frc;
+       prev_frc_valid = 1;
+}
+
 void omap3_timer_int_handler()
 {
     /* Clear all interrupts */
@@ -98,15 +117,15 @@ void omap3_timer_int_handler()
     tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
            OMAP3_TISR_TCAR_IT_FLAG;
     mmio_write(OMAP3_GPTIMER1_TISR, tisr);
-    tsc++;
 
+   frc_overflow_check();
 }
 
-/* Don't use libminlib's read_tsc_64, but our own version instead. We emulate
- * the ARM Cycle Counter (CCNT) with 1 cycle per ms. We can't rely on the
- * actual counter hardware to be working (i.e., qemu doesn't emulate it at all)
- */
+/* Use the free running clock as TSC */
 void read_tsc_64(u64_t *t)
 {
-    *t = tsc;
+       u32_t now;
+       frc_overflow_check();
+       now = read_frc();
+       *t = (u64_t) now + (high_frc << 32);
 }