mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.33.2.1 (3e4e80bfKovSGNhpWOvbDx2coqfMIw)
clean up of time/timer code: No PIT timer anymore and bugfixes to timer code
This commit is contained in:
1 parent
ce62d9e7f6
commit
2a4fc83e74
8 files changed
+212
-118
No files matched your search
+12
-20
@@ -697,37 +697,29 @@ int reprogram_ac_timer(s_time_t timeout)
|
||||
* the timer APIC on CPU does not go off every 10ms or so the linux
|
||||
* timers loose accuracy, but that shouldn't be a problem.
|
||||
*/
|
||||
//static s_time_t last_cpu0_tirq = 0;
|
||||
static s_time_t last_cpu0_tirq = 0;
|
||||
inline void smp_local_timer_interrupt(struct pt_regs * regs)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
//s_time_t diff, now;
|
||||
s_time_t diff, now;
|
||||
|
||||
|
||||
/* if CPU 0 do old timer stuff */
|
||||
if (cpu == 0) {
|
||||
|
||||
/*
|
||||
* XXX RN: the following code should be moved here or somewhere
|
||||
* else. It's currently done using the 8255 timer interrupt, which
|
||||
* I'd like to disable. But, APIC initialisation relies on it,
|
||||
* e.g., timer interrupts coming in, jiffies going up, etc. Need to
|
||||
* clean this up. Also see ./arch/i386/time.c
|
||||
*/
|
||||
#if 0
|
||||
//update_time();/* XXX should use a timer for this */
|
||||
now = NOW();
|
||||
diff = now - last_cpu0_tirq;
|
||||
|
||||
/* this uses three 64bit divisions which should be avoided!! */
|
||||
if (diff >= MILLISECS(10)) {
|
||||
/* update jiffies */
|
||||
(*(unsigned long *)&jiffies) += diff / MILLISECS(10);
|
||||
|
||||
/* do traditional linux timers */
|
||||
do_timer(regs);
|
||||
last_cpu0_tirq = now;
|
||||
if (diff <= 0) {
|
||||
printk ("System Time went backwards: %lld\n", diff);
|
||||
return;
|
||||
}
|
||||
|
||||
while (diff >= MILLISECS(10)) {
|
||||
do_timer(regs);
|
||||
diff -= MILLISECS(10);
|
||||
last_cpu0_tirq += MILLISECS(10);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* call accurate timer function */
|
||||
do_ac_timer();
|
||||
|
||||
@@ -467,3 +467,15 @@ void __init init_IRQ(void)
|
||||
|
||||
setup_irq(2, &irq2);
|
||||
}
|
||||
|
||||
/*
|
||||
* we only need the timer interrupt for callibrating the tsc<->time<->bus cycle
|
||||
* mappings. After this all timeing related functions should be run of the
|
||||
* APIC timers. This function allows us to disable the
|
||||
*/
|
||||
void __init disable_pit(void)
|
||||
{
|
||||
printk("Disable PIT. Not needed anymore\n");
|
||||
/* This is not the most elegant way, but hey. */
|
||||
disable_irq(0);
|
||||
}
|
||||
@@ -280,6 +280,7 @@ void __init start_of_day(void)
|
||||
extern void tqueue_bh(void);
|
||||
extern void immediate_bh(void);
|
||||
extern void init_timervecs(void);
|
||||
extern void disable_pit(void);
|
||||
extern void ac_timer_init(void);
|
||||
extern int setup_network_devices(void);
|
||||
extern void net_init(void);
|
||||
@@ -329,8 +330,11 @@ void __init start_of_day(void)
|
||||
* fall thru to 8259A if we have to (but slower).
|
||||
*/
|
||||
#endif
|
||||
init_xeno_time(); /* initialise the time */
|
||||
initialize_keytable(); /* call back handling for key codes */
|
||||
|
||||
disable_pit(); /* not needed anymore */
|
||||
ac_timer_init(); /* init accurate timers */
|
||||
init_xeno_time(); /* initialise the time */
|
||||
schedulers_start(); /* start scheduler for each CPU */
|
||||
|
||||
sti();
|
||||
@@ -343,7 +347,7 @@ void __init start_of_day(void)
|
||||
#endif
|
||||
do_initcalls();
|
||||
|
||||
initialize_keytable(); /* call back handling for key codes */
|
||||
|
||||
initialize_serial(); /* setup serial 'driver' (for debugging) */
|
||||
initialize_keyboard(); /* setup keyboard (also for debugging) */
|
||||
|
||||
|
||||
+58
-40
@@ -31,6 +31,7 @@
|
||||
#include <xeno/init.h>
|
||||
#include <xeno/interrupt.h>
|
||||
#include <xeno/time.h>
|
||||
#include <xeno/ac_timer.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <xeno/smp.h>
|
||||
@@ -74,15 +75,12 @@ static inline void do_timer_interrupt(int irq,
|
||||
spin_unlock(&i8259A_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* XXX RN: Want to remove this but APIC-SMP code seems to rely on it */
|
||||
do_timer(regs);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the same as the above, except we _also_ save the current
|
||||
* Time Stamp Counter value at the time of the timer interrupt, so that
|
||||
* we later on can estimate the time of day more exactly.
|
||||
* This is only temporarily. Once the APIC s up and running this
|
||||
* timer interrupt is turned off.
|
||||
*/
|
||||
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
@@ -303,8 +301,34 @@ void do_settimeofday(struct timeval *tv)
|
||||
/***************************************************************************
|
||||
* Update times
|
||||
***************************************************************************/
|
||||
/* update hypervisors notion of time */
|
||||
void update_time(void) {
|
||||
|
||||
/* update a domains notion of time */
|
||||
void update_dom_time(shared_info_t *si)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&stime_lock, flags);
|
||||
si->system_time = stime_now;
|
||||
si->st_timestamp = stime_pcc;
|
||||
spin_unlock_irqrestore(&stime_lock, flags);
|
||||
|
||||
spin_lock_irqsave(&wctime_lock, flags);
|
||||
si->tv_sec = wall_clock_time.tv_sec;
|
||||
si->tv_usec = wall_clock_time.tv_usec;
|
||||
si->wc_timestamp = wctime_st;
|
||||
si->wc_version++;
|
||||
spin_unlock_irqrestore(&wctime_lock, flags);
|
||||
|
||||
TRC(printk(" 0x%08X%08X\n", (u32)(wctime_st>>32), (u32)wctime_st));
|
||||
}
|
||||
|
||||
/*
|
||||
* Update hypervisors notion of time
|
||||
* This is done periodically of it's own timer
|
||||
*/
|
||||
static struct ac_timer update_timer;
|
||||
static void update_time(unsigned long foo)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 new_pcc;
|
||||
s_time_t new_st;
|
||||
@@ -336,26 +360,12 @@ void update_time(void) {
|
||||
TRC(printk("TIME[%02d] update time: stime_now=%lld now=%lld,wct=%ld:%ld\n",
|
||||
smp_processor_id(), stime_now, new_st, wall_clock_time.tv_sec,
|
||||
wall_clock_time.tv_usec));
|
||||
}
|
||||
|
||||
/* update a domains notion of time */
|
||||
void update_dom_time(shared_info_t *si)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&stime_lock, flags);
|
||||
si->system_time = stime_now;
|
||||
si->st_timestamp = stime_pcc;
|
||||
spin_unlock_irqrestore(&stime_lock, flags);
|
||||
|
||||
spin_lock_irqsave(&wctime_lock, flags);
|
||||
si->tv_sec = wall_clock_time.tv_sec;
|
||||
si->tv_usec = wall_clock_time.tv_usec;
|
||||
si->wc_timestamp = wctime_st;
|
||||
si->wc_version++;
|
||||
spin_unlock_irqrestore(&wctime_lock, flags);
|
||||
|
||||
TRC(printk(" 0x%08X%08X\n", (u32)(wctime_st>>32), (u32)wctime_st));
|
||||
/* reload timer */
|
||||
again:
|
||||
update_timer.expires = new_st + MILLISECS(200);
|
||||
if(add_ac_timer(&update_timer) == 1) {
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
@@ -364,13 +374,15 @@ void update_dom_time(shared_info_t *si)
|
||||
***************************************************************************/
|
||||
int __init init_xeno_time()
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
u32 cpu_cycle; /* time of one cpu cyle in pico-seconds */
|
||||
u64 scale;
|
||||
int cpu = smp_processor_id();
|
||||
u32 cpu_cycle; /* time of one cpu cyle in pico-seconds */
|
||||
u64 scale; /* scale factor */
|
||||
|
||||
spin_lock_init(&stime_lock);
|
||||
spin_lock_init(&wctime_lock);
|
||||
|
||||
printk("Init Time[%02d]:\n", cpu);
|
||||
|
||||
/* System Time */
|
||||
cpu_cycle = (u32) (1000000000LL/cpu_khz); /* in pico seconds */
|
||||
scale = 1000000000LL << 32;
|
||||
@@ -378,24 +390,30 @@ int __init init_xeno_time()
|
||||
st_scale_f = scale & 0xffffffff;
|
||||
st_scale_i = scale >> 32;
|
||||
|
||||
stime_now = (s_time_t)0;
|
||||
rdtscl(stime_pcc);
|
||||
|
||||
printk("Init Time[%02d]:\n", cpu);
|
||||
printk(".... System Time: %lldns\n", NOW());
|
||||
printk(".....cpu_cycle: %u ps\n", cpu_cycle);
|
||||
printk(".... st_scale_f: %X\n", st_scale_f);
|
||||
printk(".... st_scale_i: %X\n", st_scale_i);
|
||||
printk(".... stime_pcc: %u\n", stime_pcc);
|
||||
|
||||
/* Wall Clock time */
|
||||
wall_clock_time.tv_sec = get_cmos_time();
|
||||
wall_clock_time.tv_usec = 0;
|
||||
|
||||
/* set starting times */
|
||||
stime_now = (s_time_t)0;
|
||||
rdtscl(stime_pcc);
|
||||
wctime_st = NOW();
|
||||
|
||||
/* start timer to update time periodically */
|
||||
init_ac_timer(&update_timer);
|
||||
update_timer.function = &update_time;
|
||||
update_time(0);
|
||||
|
||||
printk(".... System Time: %lldns\n", NOW());
|
||||
printk(".....cpu_cycle: %u ps\n", cpu_cycle);
|
||||
printk(".... st_scale_f: %X\n", st_scale_f);
|
||||
printk(".... st_scale_i: %X\n", st_scale_i);
|
||||
printk(".... stime_pcc: %u\n", stime_pcc);
|
||||
|
||||
printk(".... Wall Clock: %lds %ldus\n", wall_clock_time.tv_sec,
|
||||
wall_clock_time.tv_usec);
|
||||
printk(".... wctime_st: %lld\n", wctime_st);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <xeno/time.h>
|
||||
#include <xeno/ac_timer.h>
|
||||
#include <xeno/keyhandler.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/desc.h>
|
||||
@@ -80,8 +81,6 @@ int add_ac_timer(struct ac_timer *timer)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
unsigned long flags;
|
||||
struct list_head *tmp, *prev;
|
||||
struct ac_timer *t;
|
||||
s_time_t now;
|
||||
|
||||
/* sanity checks */
|
||||
@@ -96,42 +95,54 @@ int add_ac_timer(struct ac_timer *timer)
|
||||
(u32)(timer->expires>>32), (u32)timer->expires);
|
||||
return 1;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* check if timer would be inserted at start of list */
|
||||
if ((list_empty(&ac_timers[cpu].timers)) ||
|
||||
(timer->expires <
|
||||
(list_entry(&ac_timers[cpu].timers,
|
||||
struct ac_timer, timer_list))->expires)) {
|
||||
|
||||
TRC(printk("ACT [%02d] add(): add at head\n", cpu));
|
||||
spin_lock_irqsave(&ac_timers[cpu].lock, flags);
|
||||
/*
|
||||
* Add timer to the list. If it gets added to the front we have to
|
||||
* reprogramm the timer
|
||||
*/
|
||||
if (list_empty(&ac_timers[cpu].timers)) {
|
||||
/* Reprogramm and add to head of list */
|
||||
if (!reprogram_ac_timer(timer->expires)) {
|
||||
/* failed */
|
||||
TRC(printk("ACT [%02d] add(): add at head failed\n", cpu));
|
||||
local_irq_restore(flags);
|
||||
printk("ACT [%02d] add(): add at head failed\n", cpu);
|
||||
spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
|
||||
return 1;
|
||||
}
|
||||
list_add(&timer->timer_list, &ac_timers[cpu].timers);
|
||||
|
||||
TRC(printk("ACT [%02d] add(0x%08X%08X): added at head\n", cpu,
|
||||
(u32)(timer->expires>>32), (u32)timer->expires));
|
||||
} else {
|
||||
/* find correct entry and add timer */
|
||||
prev = &ac_timers[cpu].timers;
|
||||
list_for_each(tmp, &ac_timers[cpu].timers) {
|
||||
t = list_entry(tmp, struct ac_timer, timer_list);
|
||||
if (t->expires < timer->expires) {
|
||||
list_add(&timer->timer_list, prev);
|
||||
TRC(printk("ACT [%02d] add(): added between %lld and %lld\n",
|
||||
cpu,
|
||||
list_entry(prev,struct ac_timer,timer_list)->expires,
|
||||
list_entry(tmp,struct ac_timer,timer_list)->expires));
|
||||
struct list_head *pos;
|
||||
struct ac_timer *t;
|
||||
for (pos = ac_timers[cpu].timers.next;
|
||||
pos != &ac_timers[cpu].timers;
|
||||
pos = pos->next) {
|
||||
t = list_entry(pos, struct ac_timer, timer_list);
|
||||
if (t->expires > timer->expires)
|
||||
break;
|
||||
}
|
||||
prev = tmp;
|
||||
}
|
||||
|
||||
if (pos->prev == &ac_timers[cpu].timers) {
|
||||
/* added to head, reprogramm timer */
|
||||
if (!reprogram_ac_timer(timer->expires)) {
|
||||
/* failed */
|
||||
TRC(printk("ACT [%02d] add(): add at head failed\n", cpu));
|
||||
spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
|
||||
return 1;
|
||||
}
|
||||
list_add (&(timer->timer_list), pos->prev);
|
||||
TRC(printk("ACT [%02d] add(0x%08X%08X): added at head\n", cpu,
|
||||
(u32)(timer->expires>>32), (u32)timer->expires));
|
||||
} else {
|
||||
list_add (&(timer->timer_list), pos->prev);
|
||||
TRC(printk("ACT [%02d] add(0x%08X%08X): add < exp=0x%08X%08X\n",
|
||||
cpu,
|
||||
(u32)(timer->expires>>32), (u32)timer->expires,
|
||||
(u32)(t->expires>>32), (u32)t->expires));
|
||||
}
|
||||
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -158,16 +169,17 @@ static int detach_ac_timer(struct ac_timer *timer)
|
||||
*/
|
||||
int rem_ac_timer(struct ac_timer *timer)
|
||||
{
|
||||
int res;
|
||||
int cpu = smp_processor_id();
|
||||
int res;
|
||||
unsigned long flags;
|
||||
TRC(int cpu = smp_processor_id());
|
||||
|
||||
TRC(printk("ACT [%02d] remove(): timo=%lld \n", cpu, timer->expires));
|
||||
/* sanity checks */
|
||||
|
||||
local_irq_save(flags);
|
||||
spin_lock_irqsave(&ac_timers[cpu].lock, flags);
|
||||
res = detach_ac_timer(timer);
|
||||
local_irq_restore(flags);
|
||||
spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -199,7 +211,7 @@ void do_ac_timer(void)
|
||||
struct ac_timer *t;
|
||||
struct list_head *tmp;
|
||||
|
||||
local_irq_save(flags);
|
||||
spin_lock_irqsave(&ac_timers[cpu].lock, flags);
|
||||
|
||||
do_timer_again:
|
||||
|
||||
@@ -210,7 +222,7 @@ void do_ac_timer(void)
|
||||
/* empty time list */
|
||||
if (list_empty(&ac_timers[cpu].timers)) {
|
||||
printk("ACT[%02d] do_ac_timer(): timer irq without timer\n", cpu);
|
||||
local_irq_restore(flags);
|
||||
spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -219,6 +231,8 @@ void do_ac_timer(void)
|
||||
t = list_entry(ac_timers[cpu].timers.next, struct ac_timer, timer_list);
|
||||
detach_ac_timer(t);
|
||||
|
||||
spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
|
||||
|
||||
|
||||
#ifdef AC_TIMER_STATS
|
||||
{
|
||||
@@ -258,6 +272,9 @@ void do_ac_timer(void)
|
||||
|
||||
/* check if there are other timer functions on the list */
|
||||
now = NOW();
|
||||
|
||||
spin_lock_irqsave(&ac_timers[cpu].lock, flags);
|
||||
|
||||
if (!list_empty(&ac_timers[cpu].timers)) {
|
||||
list_for_each(tmp, &ac_timers[cpu].timers) {
|
||||
t = list_entry(tmp, struct ac_timer, timer_list);
|
||||
@@ -265,8 +282,10 @@ void do_ac_timer(void)
|
||||
cpu, now, t->expires));
|
||||
if (t->expires <= now) {
|
||||
detach_ac_timer(t);
|
||||
spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
|
||||
if (t->function != NULL)
|
||||
t->function(t->data);
|
||||
spin_lock_irqsave(&ac_timers[cpu].lock, flags);
|
||||
now = NOW();
|
||||
} else {
|
||||
TRC(printk("ACT [%02d] do(): break1\n", cpu));
|
||||
@@ -286,7 +305,47 @@ void do_ac_timer(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
|
||||
TRC(printk("ACT [%02d] do(): end\n", cpu));
|
||||
}
|
||||
|
||||
/*
|
||||
* debug dump_queue
|
||||
* arguments: queue head, name of queue
|
||||
*/
|
||||
static void dump_tqueue(struct list_head *queue, char *name)
|
||||
{
|
||||
struct list_head *list;
|
||||
int loop = 0;
|
||||
struct ac_timer *t;
|
||||
|
||||
printk ("QUEUE %s %lx n: %lx, p: %lx\n", name, (unsigned long)queue,
|
||||
(unsigned long) queue->next, (unsigned long) queue->prev);
|
||||
list_for_each (list, queue) {
|
||||
t = list_entry(list, struct ac_timer, timer_list);
|
||||
printk (" %s %d : %lx ex=0x%08X%08X %lu n: %lx, p: %lx\n",
|
||||
name, loop++,
|
||||
(unsigned long)list,
|
||||
(u32)(t->expires>>32), (u32)t->expires, t->data,
|
||||
(unsigned long)list->next, (unsigned long)list->prev);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void dump_timerq(u_char key, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
u_long flags;
|
||||
s_time_t now = NOW();
|
||||
|
||||
printk("Dumping ac_timer queues for cpu 0: NOW=0x%08X%08X\n",
|
||||
(u32)(now>>32), (u32)now);
|
||||
|
||||
spin_lock_irqsave(&ac_timers[0].lock, flags);
|
||||
dump_tqueue(&ac_timers[0].timers, "ac_time");
|
||||
spin_unlock_irqrestore(&ac_timers[0].lock, flags);
|
||||
printk("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -303,5 +362,6 @@ void __init ac_timer_init(void)
|
||||
INIT_LIST_HEAD(&ac_timers[i].timers);
|
||||
spin_lock_init(&ac_timers[i].lock);
|
||||
}
|
||||
/* ac_timer_debug(0); */
|
||||
|
||||
add_key_handler('a', dump_timerq, "dump ac_timer queues");
|
||||
}
|
||||
@@ -282,6 +282,9 @@ asmlinkage void schedule(void)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The scheduling timer.
|
||||
*/
|
||||
static __cacheline_aligned int count[NR_CPUS];
|
||||
static void sched_timer(unsigned long foo)
|
||||
{
|
||||
@@ -290,14 +293,35 @@ static void sched_timer(unsigned long foo)
|
||||
s_time_t now;
|
||||
int res;
|
||||
|
||||
/* reschedule after each 5 ticks */
|
||||
if (count[cpu] >= 5) {
|
||||
set_bit(_HYP_EVENT_NEED_RESCHED, &curr->hyp_events);
|
||||
count[cpu] = 0;
|
||||
if (cpu == 0)
|
||||
update_time(); /* XXX RN: Should be moved on its own timer */
|
||||
}
|
||||
count[cpu]++;
|
||||
|
||||
/*
|
||||
* deliver virtual timer interrups to domains if we are CPU 0
|
||||
* XXX RN: We don't have a per CPU list of domains yet. Otherwise
|
||||
* would use that. Plus, this should be removed anyway once
|
||||
* Domains "know" about virtual time and timeouts. But, it's better
|
||||
* here then where it was before.
|
||||
*/
|
||||
if (cpu == 0) {
|
||||
struct task_struct *p;
|
||||
unsigned long cpu_mask = 0;
|
||||
|
||||
/* send virtual timer interrupt */
|
||||
read_lock(&tasklist_lock);
|
||||
p = &idle0_task;
|
||||
do {
|
||||
cpu_mask |= mark_guest_event(p, _EVENT_TIMER);
|
||||
}
|
||||
while ( (p = p->next_task) != &idle0_task );
|
||||
read_unlock(&tasklist_lock);
|
||||
guest_event_notify(cpu_mask);
|
||||
}
|
||||
|
||||
again:
|
||||
now = NOW();
|
||||
s_timer[cpu].expires = now + MILLISECS(10);
|
||||
@@ -310,6 +334,8 @@ static void sched_timer(unsigned long foo)
|
||||
goto again;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialise the data structures
|
||||
*/
|
||||
|
||||
@@ -586,27 +586,12 @@ void timer_bh(void)
|
||||
|
||||
void do_timer(struct pt_regs *regs)
|
||||
{
|
||||
struct task_struct *p;
|
||||
shared_info_t *s;
|
||||
unsigned long cpu_mask = 0;
|
||||
|
||||
(*(unsigned long *)&jiffies)++;
|
||||
|
||||
if ( !using_apic_timer )
|
||||
update_process_times(user_mode(regs));
|
||||
|
||||
/* XXX RN: Move this for virtual domain time timer interrupts */
|
||||
read_lock(&tasklist_lock);
|
||||
p = &idle0_task;
|
||||
do {
|
||||
s = p->shared_info;
|
||||
cpu_mask |= mark_guest_event(p, _EVENT_TIMER);
|
||||
}
|
||||
while ( (p = p->next_task) != &idle0_task );
|
||||
read_unlock(&tasklist_lock);
|
||||
|
||||
guest_event_notify(cpu_mask);
|
||||
|
||||
mark_bh(TIMER_BH);
|
||||
if (TQ_ACTIVE(tq_timer))
|
||||
mark_bh(TQUEUE_BH);
|
||||
|
||||
@@ -41,9 +41,6 @@ typedef s64 s_time_t; /* System time */
|
||||
extern u32 stime_pcc; /* cycle counter value at last timer irq */
|
||||
extern s_time_t stime_now; /* time in ns at last timer IRQ */
|
||||
|
||||
/* update time variables once in a while */
|
||||
extern void update_time(void);
|
||||
|
||||
/*
|
||||
* Domain Virtual Time
|
||||
*/
|
||||
|
||||