//////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: SystemClock.cs // // Note: // using System; using System.Runtime.CompilerServices; using Microsoft.Singularity.Hal; namespace Microsoft.Singularity { /// /// The system clock provides an interface to the clock device that /// caters for the difference between the Clock and UTC. The Clock time /// is typically held in persistent storage and set by the user. The /// clock time is typically stored local time rather than UTC. /// [CLSCompliant(false)] public class SystemClock { private static HalClock clockDevice; private static long rtcUtcOffset; private const int year = 2007; private const int month = 1; private const int day = 1; /// /// Constructor. /// Underlying clock device to use. /// The UTC offset of the Real-Time Clock /// associated with the clock device. /// [NoHeapAllocation] public static void Initialize(HalClock device, long rtcUtcDelta) { clockDevice = device; rtcUtcOffset = rtcUtcDelta; } /// /// Get the offset applied to the Real-Time Clock device. /// [NoHeapAllocation] public static long GetRtcUtcOffset(long ticks) { return rtcUtcOffset; } /// /// Set the offset applied to the Real-Time Clock device. /// Offset in units of 100ns. /// true on success, false if offset is greater than 12 hours. /// /// [NoHeapAllocation] public static bool SetRtcUtcOffset(long ticks) { if (UtcOffsetValid(ticks) == false) return false; rtcUtcOffset = ticks; return true; } public static DateTime GetUtcTime() { if (clockDevice == null) { // the clock device is not initialized yet // This will happen when we try to set the times for // the inital objects in the Directory Service // We will cons up a fixed value; return new DateTime(year,month,day); } DateTime rtc = new DateTime(clockDevice.GetRtcTime()); return rtc.AddTicks(rtcUtcOffset); } public static void SetUtcTime(DateTime now) { DateTime utc = now.AddTicks(-rtcUtcOffset); clockDevice.SetRtcTime(utc.Ticks); } /// Get the time elapsed since booting. All /// kernel timers and timing calculations should be /// based on the time returned by this method to avoid /// problems following TimeZone changes or time updates. /// Time in units of 100ns. /// public static TimeSpan KernelUpTime { [NoHeapAllocation] get { return new TimeSpan(clockDevice.GetKernelTicks()); } } /// Get the time since booting in kernel ticks of 100ns. /// // //[NoHeapAllocation] //public static long GetKernelTicks() //{ // return clockDevice.GetKernelTicks(); //} // [NoHeapAllocation] private static bool UtcOffsetValid(long offset) { return (offset >= TimeSpan.TicksPerDay / 2 && offset <= TimeSpan.TicksPerDay / 2); } } }