ia64/xen-unstable

view extras/mini-os/time.c @ 810:3f44ecdcb631

bitkeeper revision 1.499 (3f867c85oOyUdtcboCzrLgktKtvdgA)

ac_timer.h, ac_timer.c:
Xen ac timers now use a heap to find earliest timeout.
author kaf24@scramble.cl.cam.ac.uk
date Fri Oct 10 09:31:49 2003 +0000 (2003-10-10)
parents 34473973889b
children 71f9c171157e
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
2 ****************************************************************************
3 * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
4 ****************************************************************************
5 *
6 * File: time.c
7 * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
8 * Changes:
9 *
10 * Date: Jul 2003
11 *
12 * Environment: Xen Minimal OS
13 * Description: Simple time and timer functions
14 *
15 ****************************************************************************
16 * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
17 ****************************************************************************
18 */
21 #include <os.h>
22 #include <types.h>
23 #include <hypervisor.h>
24 #include <events.h>
25 #include <time.h>
26 #include <lib.h>
28 /************************************************************************
29 * Time functions
30 *************************************************************************/
32 static unsigned int rdtsc_bitshift;
33 static u32 st_scale_f;
34 static u32 st_scale_i;
35 static u32 shadow_st_pcc;
36 static s_time_t shadow_st;
37 static u32 shadow_wc_version=0;
38 static long shadow_tv_sec;
39 static long shadow_tv_usec;
40 static s_time_t shadow_wc_timestamp;
42 /*
43 * System time.
44 * We need to read the values from the shared info page "atomically"
45 * and use the cycle counter value as the "version" number. Clashes
46 * should be very rare.
47 */
48 inline s_time_t get_s_time(void)
49 {
50 s32 delta_tsc;
51 u32 low;
52 u64 delta, tsc;
53 u32 version;
54 u64 cpu_freq, scale;
56 /* check if our values are still up-to-date */
57 while ( (version = HYPERVISOR_shared_info->wc_version) !=
58 shadow_wc_version )
59 {
60 barrier();
62 shadow_wc_version = version;
63 shadow_tv_sec = HYPERVISOR_shared_info->tv_sec;
64 shadow_tv_usec = HYPERVISOR_shared_info->tv_usec;
65 shadow_wc_timestamp = HYPERVISOR_shared_info->wc_timestamp;
66 shadow_st_pcc = HYPERVISOR_shared_info->st_timestamp;
67 shadow_st = HYPERVISOR_shared_info->system_time;
69 rdtsc_bitshift = HYPERVISOR_shared_info->rdtsc_bitshift;
70 cpu_freq = HYPERVISOR_shared_info->cpu_freq;
72 /* XXX cpu_freq as u32 limits it to 4.29 GHz. Get a better do_div! */
73 scale = 1000000000LL << (32 + rdtsc_bitshift);
74 scale /= cpu_freq;
75 st_scale_f = scale & 0xffffffff;
76 st_scale_i = scale >> 32;
78 barrier();
79 }
81 rdtscll(tsc);
82 low = (u32)(tsc >> rdtsc_bitshift);
83 delta_tsc = (s32)(low - shadow_st_pcc);
84 if ( unlikely(delta_tsc < 0) ) delta_tsc = 0;
85 delta = ((u64)delta_tsc * st_scale_f);
86 delta >>= 32;
87 delta += ((u64)delta_tsc * st_scale_i);
89 return shadow_st + delta;
90 }
93 /*
94 * Wallclock time.
95 * Based on what the hypervisor tells us, extrapolated using system time.
96 * Again need to read a number of values from the shared page "atomically".
97 * this time using a version number.
98 */
99 void gettimeofday(struct timeval *tv)
100 {
101 long usec, sec;
102 u64 now;
104 now = get_s_time();
105 usec = ((unsigned long)(now-shadow_wc_timestamp))/1000;
106 sec = shadow_tv_sec;
107 usec += shadow_tv_usec;
109 while ( usec >= 1000000 )
110 {
111 usec -= 1000000;
112 sec++;
113 }
115 tv->tv_sec = sec;
116 tv->tv_usec = usec;
117 }
120 static void timer_handler(int ev, struct pt_regs *regs)
121 {
122 static int i;
123 s_time_t now;
125 i++;
126 if (i >= 1000) {
127 now = get_s_time();
128 printf("T(%lld)\n", now);
129 i = 0;
130 }
131 }
134 void init_time(void)
135 {
136 u64 __cpu_khz;
137 unsigned long cpu_khz;
139 __cpu_khz = HYPERVISOR_shared_info->cpu_freq;
140 cpu_khz = (u32) (__cpu_khz/1000);
142 printk("Xen reported: %lu.%03lu MHz processor.\n",
143 cpu_khz / 1000, cpu_khz % 1000);
145 add_ev_action(EV_TIMER, &timer_handler);
146 enable_ev_action(EV_TIMER);
147 enable_hypervisor_event(EV_TIMER);
149 }