bitkeeper revision 1.1108.3.1 (40fc449eExRZSW5dU1TAzdlOTRDqMQ)

Add HYPERVISOR_block support.
Not enabled yet since it adds a 5 seconds long delay during boot.
This commit is contained in:
cl349@freefall.cl.cam.ac.uk committed 2004-07-19 22:01:02 +00:00
1 parent e17fa59f09
commit 95ea1d92ca
3 files changed
+110 -6

No files matched your search

+4
View File
@@ -16,6 +16,10 @@ config ARCH_XEN
default y
config NO_IDLE_HZ
bool
default y
source "init/Kconfig"
#config VT
@@ -87,6 +87,17 @@ EXPORT_SYMBOL(i8253_lock);
struct timer_opts *cur_timer = &timer_none;
/* These are peridically updated in shared_info, and then copied here. */
static u32 shadow_tsc_stamp;
static u64 shadow_system_time;
static u32 shadow_time_version;
static struct timeval shadow_tv;
/* Keep track of last time we did processing/updating of jiffies and xtime. */
static u64 processed_system_time; /* System time (ns) at last processing. */
#define NS_PER_TICK (1000000000ULL/HZ)
/*
* This version of gettimeofday has microsecond resolution
* and better than microsecond precision on fast x86 machines with TSC.
@@ -203,6 +214,24 @@ unsigned long long monotonic_clock(void)
EXPORT_SYMBOL(monotonic_clock);
/*
* Reads a consistent set of time-base values from Xen, into a shadow data
* area. Must be called with the xtime_lock held for writing.
*/
static void __get_time_values_from_xen(void)
{
do {
shadow_time_version = HYPERVISOR_shared_info->time_version2;
rmb();
shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec;
shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec;
shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp.tsc_bits;
shadow_system_time = HYPERVISOR_shared_info->system_time;
rmb();
}
while ( shadow_time_version != HYPERVISOR_shared_info->time_version1 );
}
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
@@ -210,6 +239,9 @@ EXPORT_SYMBOL(monotonic_clock);
static inline void do_timer_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
s64 delta;
unsigned long ticks = 0;
#ifdef CONFIG_X86_IO_APIC
if (timer_ack) {
/*
@@ -226,7 +258,23 @@ static inline void do_timer_interrupt(int irq, void *dev_id,
}
#endif
do_timer_interrupt_hook(regs);
__get_time_values_from_xen();
delta = (s64)(shadow_system_time - processed_system_time);
if (delta < 0) {
printk("Timer ISR: Time went backwards: %lld\n", delta);
return;
}
/* Process elapsed jiffies since last call. */
while (delta >= NS_PER_TICK) {
ticks++;
delta -= NS_PER_TICK;
processed_system_time += NS_PER_TICK;
if (regs)
do_timer_interrupt_hook(regs);
}
#if 0 /* XEN PRIV */
/*
@@ -288,8 +336,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
cur_timer->mark_offset();
if (regs) /* XXXcl check regs in do_timer_interrupt */
do_timer_interrupt(irq, NULL, regs);
do_timer_interrupt(irq, NULL, regs);
write_sequnlock(&xtime_lock);
return IRQ_HANDLED;
@@ -410,3 +457,51 @@ void __init time_init(void)
(void)setup_irq(time_irq, &irq_timer);
}
/* Convert jiffies to system time. Call with xtime_lock held for reading. */
static inline u64 __jiffies_to_st(unsigned long j)
{
return processed_system_time + ((j - jiffies) * NS_PER_TICK);
}
/*
* This function works out when the the next timer function has to be
* executed (by looking at the timer list) and sets the Xen one-shot
* domain timer to the appropriate value. This is typically called in
* cpu_idle() before the domain blocks.
*
* The function returns a non-0 value on error conditions.
*
* It must be called with interrupts disabled.
*/
extern spinlock_t timerlist_lock;
int set_timeout_timer(void)
{
struct timer_list *timer;
u64 alarm = 0;
int ret = 0;
spin_lock(&timerlist_lock);
/*
* This is safe against long blocking (since calculations are not based on
* TSC deltas). It is also safe against warped system time since
* suspend-resume is cooperative and we would first get locked out. It is
* safe against normal updates of jiffies since interrupts are off.
*/
alarm = __jiffies_to_st(next_timer_interrupt());
#if 0
/* Tasks on the timer task queue expect to be executed on the next tick. */
if ( TQ_ACTIVE(tq_timer) )
alarm = __jiffies_to_st(jiffies + 1);
#endif
/* Failure is pretty bad, but we'd best soldier on. */
if ( HYPERVISOR_set_timer_op(alarm) != 0 )
ret = -1;
spin_unlock(&timerlist_lock);
return ret;
}
@@ -10,11 +10,16 @@
void xen_cpu_idle (void)
{
// local_irq_disable();
local_irq_disable();
if (need_resched()) {
// local_irq_enable();
local_irq_enable();
return;
}
// local_irq_enable();
if (0 && set_timeout_timer() == 0) {
/* NB. Blocking reenable events in a race-free manner. */
HYPERVISOR_block();
return;
}
local_irq_enable();
HYPERVISOR_yield();
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.