[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] RE: [RFC] Correct/fast timestamping in apps under Xen [0 of 4]
OK, here'e some pseudo-code to describe the decision tree an app would go through -- once at startup -- to probe the environment and determine which timestamp mechanism is the best, meaning all of correct AND fastest AND highest resolution. Also following that is the code an app would use whenever a timestamp is needed (could be a static inline function to avoid function call overhead). Remember that this is ONLY needed by apps that must obtain a timestamp at a high frequency, say >2K/core/sec. At lower frequencies, TSC emulation or calling an OS intrinsic should be sufficient. In some environments (e.g. if/when pvclock+ vsyscall is implemented), an OS intrinsic may be faster than emulation. However, there is no way to probe this so, if necessary, we determine which is fastest by measuring both. The pvrdtscp mechanism, which must be proactively configured for a guest, uses the rdtscp instruction to return TSC and the guest incarnation number (which changes infrequently). If the app is currently running on hardware which either does not support rdtscp or doesn't have a reliable TSC, zero is returned in place of the incarnation number and Xen system time (in nsec) is returned instead of TSC. Legend: XEN_* indicates information obtained by the app directly from Xen (using a TBD mechanism). All other functions are in-app calls. Dan ==================== /* run once at app startup */ if (running_on_xen()) timestamp_mech = TS_NATIVE; if (XEN_guest_is_landlocked() && XEN_tsc_is_reliable()) timestamp_mech = TS_RDTSC_SCALE; timestamp_scale = XEN_tsc_scale(); } else if (XEN_guest_has_pvrdtscp()) timestamp_mech = TS_PVRDTSCP; else if (XEN_guest_tsc_emulated()) { os_intr_cycles = measure_os_intrinsic(); tsc_emul_cycles = measure_tsc_emulation(); if (tsc_emul_cycles < os_intr_cycles) { timestamp_mech = TS_RDTSC_NSEC; else timestamp_mech = TS_OS_INTRINSIC; } /* returns monotonically increasing timestamp (nsec) */ u64 get_nsec_timestamp(void) { static u64 last = 0; u64 now; if (timestamp_mech == TS_NATIVE) now = native_timestamp(); else if (timestamp_mech == TS_PVRDTSCP) { static u32 last_aux = 0; u32 this_aux; now = rdtscp(&this_aux); if (this_aux != 0) { while (this_aux != last_aux) { /* occurs only very rarely */ last_aux = this_aux; timestamp_scale = XEN_tsc_scale(); now = rdtscp(&this_aux); } now = ts_scale(timestamp_scale,now); } /* this_aux == 0 means was emulated and already have nsec */ } else if (timestamp_mech == TS_RDTSC_NSEC) now = rdtsc(); else if (timestamp_mech == TS_RDTSC_SCALE) now = ts_scale(timestamp_scale,rdtsc()); else /* TS_OS_INTRINSIC */ now = os_intrinsic_get_nsec(); /* ensure monotonically increasing */ if ((s64)(now - last) > 0) last = now; else now = ++last; return now; } _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |