////////////////////////////////////////////////////////////////////////////////
//
// 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;
///
/// 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()
{
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);
}
}
}