kernel: scheduling fix for ARM
. make read_tsc_64 use the free-running clock, significantly improving scheduling behaviour Change-Id: Idf6a12f6e26be7fe3b3664c278cae846d8b2a442
This commit is contained in:
parent
af18db5668
commit
8ea66915f2
@ -52,13 +52,13 @@ void cycles_accounting_init(void)
|
|||||||
|
|
||||||
void context_stop(struct proc * p)
|
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);
|
u64_t * __tsc_ctr_switch = get_cpulocal_var_ptr(tsc_ctr_switch);
|
||||||
|
|
||||||
read_tsc_64(&tsc);
|
read_tsc_64(&tsc);
|
||||||
p->p_cycles = add64(p->p_cycles, sub64(tsc, *__tsc_ctr_switch));
|
tsc_delta = tsc - *__tsc_ctr_switch;
|
||||||
|
p->p_cycles += tsc_delta;
|
||||||
tsc_delta = sub64(tsc, *__tsc_ctr_switch);
|
|
||||||
|
|
||||||
if(kbill_ipc) {
|
if(kbill_ipc) {
|
||||||
kbill_ipc->p_kipc_cycles =
|
kbill_ipc->p_kipc_cycles =
|
||||||
@ -79,18 +79,11 @@ void context_stop(struct proc * p)
|
|||||||
*/
|
*/
|
||||||
if (p->p_endpoint >= 0) {
|
if (p->p_endpoint >= 0) {
|
||||||
#if DEBUG_RACE
|
#if DEBUG_RACE
|
||||||
make_zero64(p->p_cpu_time_left);
|
p->p_cpu_time_left = 0;
|
||||||
#else
|
#else
|
||||||
/* if (tsc_delta < p->p_cpu_time_left) in 64bit */
|
if (tsc_delta < p->p_cpu_time_left) {
|
||||||
if (ex64hi(tsc_delta) < ex64hi(p->p_cpu_time_left) ||
|
p->p_cpu_time_left -= tsc_delta;
|
||||||
(ex64hi(tsc_delta) == ex64hi(p->p_cpu_time_left) &&
|
} else p->p_cpu_time_left = 0;
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ static int freepdes[MAXFREEPDES];
|
|||||||
|
|
||||||
static u32_t phys_get32(phys_bytes v);
|
static u32_t phys_get32(phys_bytes v);
|
||||||
|
|
||||||
|
extern vir_bytes omap3_gptimer10_base = OMAP3_GPTIMER10_BASE;
|
||||||
|
|
||||||
void mem_clear_mapcache(void)
|
void mem_clear_mapcache(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -763,7 +765,7 @@ int arch_phys_map_reply(const int index, const vir_bytes addr)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
else if (index == frclock_index) {
|
else if (index == frclock_index) {
|
||||||
minix_kerninfo.minix_frclock = addr;
|
omap3_gptimer10_base = minix_kerninfo.minix_frclock = addr;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
#include "omap_intr.h"
|
#include "omap_intr.h"
|
||||||
|
|
||||||
static irq_hook_t omap3_timer_hook; /* interrupt handler hook */
|
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)
|
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);
|
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()
|
void omap3_timer_int_handler()
|
||||||
{
|
{
|
||||||
/* Clear all interrupts */
|
/* Clear all interrupts */
|
||||||
@ -98,15 +117,15 @@ void omap3_timer_int_handler()
|
|||||||
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
|
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
|
||||||
OMAP3_TISR_TCAR_IT_FLAG;
|
OMAP3_TISR_TCAR_IT_FLAG;
|
||||||
mmio_write(OMAP3_GPTIMER1_TISR, tisr);
|
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
|
/* Use the free running clock as TSC */
|
||||||
* 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)
|
|
||||||
*/
|
|
||||||
void read_tsc_64(u64_t *t)
|
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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user