aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services/Time/Clock
diff options
context:
space:
mode:
authorThomas Guillemard <me@thog.eu>2019-07-25 16:44:51 +0200
committergdkchan <gab.dark.100@gmail.com>2019-07-25 11:44:51 -0300
commit54b79dffa8eafe9da9765329930e8832ae90ae83 (patch)
tree1ba6b60288997c8ce21a72bbd28e3efb7b8db2d7 /Ryujinx.HLE/HOS/Services/Time/Clock
parentd254548548398977a45dbfc03f2cc091c5a74f03 (diff)
Implement time:* 4.0.0 commands (#736)
* Abstract SteadyClockCore to follow Nintendo changes in 4.x This is the ground work for 4.0.0 support * Implement TickBasedSteadyClockCore Preparation for the ephemeral clock. * Refactor SystemClockCore to follow 4.0.0 changes * Implement EphemeralNetworkSystemClock * Implement GetSnapshotClock & GetSnapshotClockFromSystemClockContext * Implement CalculateStandardUserSystemClockDifferenceByUser & CalculateSpanBetween * Remove an outdated comment & unused import * Fix a nit and GetClockSnapshot * Address comment
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Time/Clock')
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/Clock/ClockTypes.cs47
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs27
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs42
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs42
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs107
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs15
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs113
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs30
-rw-r--r--Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs40
9 files changed, 288 insertions, 175 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/ClockTypes.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/ClockTypes.cs
index 860f5ad2..c70819c0 100644
--- a/Ryujinx.HLE/HOS/Services/Time/Clock/ClockTypes.cs
+++ b/Ryujinx.HLE/HOS/Services/Time/Clock/ClockTypes.cs
@@ -7,6 +7,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
[StructLayout(LayoutKind.Sequential)]
struct TimeSpanType
{
+ private const long NanoSecondsPerSecond = 1000000000;
+
public long NanoSeconds;
public TimeSpanType(long nanoSeconds)
@@ -16,12 +18,17 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
public long ToSeconds()
{
- return NanoSeconds / 1000000000;
+ return NanoSeconds / NanoSecondsPerSecond;
+ }
+
+ public static TimeSpanType FromSeconds(long seconds)
+ {
+ return new TimeSpanType(seconds * NanoSecondsPerSecond);
}
public static TimeSpanType FromTicks(ulong ticks, ulong frequency)
{
- return new TimeSpanType((long)ticks * 1000000000 / (long)frequency);
+ return FromSeconds((long)ticks / (long)frequency);
}
}
@@ -59,4 +66,40 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
public long Offset;
public SteadyClockTimePoint SteadyTimePoint;
}
+
+ [StructLayout(LayoutKind.Sequential, Size = 0xD0)]
+ struct ClockSnapshot
+ {
+ public SystemClockContext UserContext;
+ public SystemClockContext NetworkContext;
+ public long UserTime;
+ public long NetworkTime;
+ public CalendarTime UserCalendarTime;
+ public CalendarTime NetworkCalendarTime;
+ public CalendarAdditionalInfo UserCalendarAdditionalTime;
+ public CalendarAdditionalInfo NetworkCalendarAdditionalTime;
+ public SteadyClockTimePoint SteadyClockTimePoint;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x24)]
+ public char[] LocationName;
+
+ [MarshalAs(UnmanagedType.I1)]
+ public bool IsAutomaticCorrectionEnabled;
+ public byte Type;
+ public ushort Unknown;
+
+ public static ResultCode GetCurrentTime(out long currentTime, SteadyClockTimePoint steadyClockTimePoint, SystemClockContext context)
+ {
+ currentTime = 0;
+
+ if (steadyClockTimePoint.ClockSourceId == context.SteadyTimePoint.ClockSourceId)
+ {
+ currentTime = steadyClockTimePoint.TimePoint + context.Offset;
+
+ return ResultCode.Success;
+ }
+
+ return ResultCode.TimeMismatch;
+ }
+ }
}
diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs
new file mode 100644
index 00000000..8e9073a4
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Time/Clock/EphemeralNetworkSystemClockCore.cs
@@ -0,0 +1,27 @@
+namespace Ryujinx.HLE.HOS.Services.Time.Clock
+{
+ class EphemeralNetworkSystemClockCore : SystemClockCore
+ {
+ private static EphemeralNetworkSystemClockCore _instance;
+
+ public static EphemeralNetworkSystemClockCore Instance
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ _instance = new EphemeralNetworkSystemClockCore(TickBasedSteadyClockCore.Instance);
+ }
+
+ return _instance;
+ }
+ }
+
+ public EphemeralNetworkSystemClockCore(SteadyClockCore steadyClockCore) : base(steadyClockCore) { }
+
+ public override ResultCode Flush(SystemClockContext context)
+ {
+ return ResultCode.Success;
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs
index 16550199..a1727976 100644
--- a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs
+++ b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardLocalSystemClockCore.cs
@@ -1,34 +1,23 @@
-using Ryujinx.HLE.HOS.Kernel.Threading;
-
-namespace Ryujinx.HLE.HOS.Services.Time.Clock
+namespace Ryujinx.HLE.HOS.Services.Time.Clock
{
class StandardLocalSystemClockCore : SystemClockCore
{
- private SteadyClockCore _steadyClockCore;
- private SystemClockContext _context;
-
- private static StandardLocalSystemClockCore instance;
+ private static StandardLocalSystemClockCore _instance;
public static StandardLocalSystemClockCore Instance
{
get
{
- if (instance == null)
+ if (_instance == null)
{
- instance = new StandardLocalSystemClockCore(SteadyClockCore.Instance);
+ _instance = new StandardLocalSystemClockCore(StandardSteadyClockCore.Instance);
}
- return instance;
+ return _instance;
}
}
- public StandardLocalSystemClockCore(SteadyClockCore steadyClockCore)
- {
- _steadyClockCore = steadyClockCore;
- _context = new SystemClockContext();
-
- _context.SteadyTimePoint.ClockSourceId = steadyClockCore.GetClockSourceId();
- }
+ public StandardLocalSystemClockCore(StandardSteadyClockCore steadyClockCore) : base(steadyClockCore) {}
public override ResultCode Flush(SystemClockContext context)
{
@@ -36,24 +25,5 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
return ResultCode.Success;
}
-
- public override SteadyClockCore GetSteadyClockCore()
- {
- return _steadyClockCore;
- }
-
- public override ResultCode GetSystemClockContext(KThread thread, out SystemClockContext context)
- {
- context = _context;
-
- return ResultCode.Success;
- }
-
- public override ResultCode SetSystemClockContext(SystemClockContext context)
- {
- _context = context;
-
- return ResultCode.Success;
- }
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs
index c00f460e..5037fb60 100644
--- a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs
+++ b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardNetworkSystemClockCore.cs
@@ -1,35 +1,28 @@
-using System;
-using Ryujinx.HLE.HOS.Kernel.Threading;
+using Ryujinx.HLE.HOS.Kernel.Threading;
namespace Ryujinx.HLE.HOS.Services.Time.Clock
{
class StandardNetworkSystemClockCore : SystemClockCore
{
- private SteadyClockCore _steadyClockCore;
- private SystemClockContext _context;
private TimeSpanType _standardNetworkClockSufficientAccuracy;
- private static StandardNetworkSystemClockCore instance;
+ private static StandardNetworkSystemClockCore _instance;
public static StandardNetworkSystemClockCore Instance
{
get
{
- if (instance == null)
+ if (_instance == null)
{
- instance = new StandardNetworkSystemClockCore(SteadyClockCore.Instance);
+ _instance = new StandardNetworkSystemClockCore(StandardSteadyClockCore.Instance);
}
- return instance;
+ return _instance;
}
}
- public StandardNetworkSystemClockCore(SteadyClockCore steadyClockCore)
+ public StandardNetworkSystemClockCore(StandardSteadyClockCore steadyClockCore) : base(steadyClockCore)
{
- _steadyClockCore = steadyClockCore;
- _context = new SystemClockContext();
-
- _context.SteadyTimePoint.ClockSourceId = steadyClockCore.GetClockSourceId();
_standardNetworkClockSufficientAccuracy = new TimeSpanType(0);
}
@@ -40,25 +33,6 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
return ResultCode.Success;
}
- public override SteadyClockCore GetSteadyClockCore()
- {
- return _steadyClockCore;
- }
-
- public override ResultCode GetSystemClockContext(KThread thread, out SystemClockContext context)
- {
- context = _context;
-
- return ResultCode.Success;
- }
-
- public override ResultCode SetSystemClockContext(SystemClockContext context)
- {
- _context = context;
-
- return ResultCode.Success;
- }
-
public bool IsStandardNetworkSystemClockAccuracySufficient(KThread thread)
{
SteadyClockCore steadyClockCore = GetSteadyClockCore();
@@ -66,7 +40,9 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
bool isStandardNetworkClockSufficientAccuracy = false;
- if (_context.SteadyTimePoint.GetSpanBetween(currentTimePoint, out long outSpan) == ResultCode.Success)
+ ResultCode result = GetSystemClockContext(thread, out SystemClockContext context);
+
+ if (result == ResultCode.Success && context.SteadyTimePoint.GetSpanBetween(currentTimePoint, out long outSpan) == ResultCode.Success)
{
isStandardNetworkClockSufficientAccuracy = outSpan * 1000000000 < _standardNetworkClockSufficientAccuracy.NanoSeconds;
}
diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs
new file mode 100644
index 00000000..fea5bf2f
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardSteadyClockCore.cs
@@ -0,0 +1,107 @@
+using Ryujinx.HLE.HOS.Kernel.Threading;
+using Ryujinx.HLE.HOS.Services.Bpc;
+
+namespace Ryujinx.HLE.HOS.Services.Time.Clock
+{
+ class StandardSteadyClockCore : SteadyClockCore
+ {
+ private long _setupValue;
+ private ResultCode _setupResultCode;
+ private bool _isRtcResetDetected;
+ private TimeSpanType _testOffset;
+ private TimeSpanType _internalOffset;
+
+ private static StandardSteadyClockCore _instance;
+
+ public static StandardSteadyClockCore Instance
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ _instance = new StandardSteadyClockCore();
+ }
+
+ return _instance;
+ }
+ }
+
+ private StandardSteadyClockCore()
+ {
+ _testOffset = new TimeSpanType(0);
+ _internalOffset = new TimeSpanType(0);
+ }
+
+ public override SteadyClockTimePoint GetTimePoint(KThread thread)
+ {
+ SteadyClockTimePoint result = new SteadyClockTimePoint
+ {
+ TimePoint = 0,
+ ClockSourceId = GetClockSourceId()
+ };
+
+ TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(thread.Context.ThreadState.CntpctEl0, thread.Context.ThreadState.CntfrqEl0);
+
+ result.TimePoint = _setupValue + ticksTimeSpan.ToSeconds();
+
+ return result;
+ }
+
+ public override TimeSpanType GetTestOffset()
+ {
+ return _testOffset;
+ }
+
+ public override void SetTestOffset(TimeSpanType testOffset)
+ {
+ _testOffset = testOffset;
+ }
+
+ public override ResultCode GetRtcValue(out ulong rtcValue)
+ {
+ return (ResultCode)IRtcManager.GetExternalRtcValue(out rtcValue);
+ }
+
+ public bool IsRtcResetDetected()
+ {
+ return _isRtcResetDetected;
+ }
+
+ public override TimeSpanType GetInternalOffset()
+ {
+ return _internalOffset;
+ }
+
+ public override void SetInternalOffset(TimeSpanType internalOffset)
+ {
+ _internalOffset = internalOffset;
+ }
+
+ public override ResultCode GetSetupResultValue()
+ {
+ return _setupResultCode;
+ }
+
+ public void ConfigureSetupValue()
+ {
+ int retry = 0;
+
+ ResultCode result = ResultCode.Success;
+
+ while (retry < 20)
+ {
+ result = (ResultCode)IRtcManager.GetExternalRtcValue(out ulong rtcValue);
+
+ if (result == ResultCode.Success)
+ {
+ _setupValue = (long)rtcValue;
+ break;
+ }
+
+ retry++;
+ }
+
+ _setupResultCode = result;
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs
index 00f296ad..c98b0064 100644
--- a/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs
+++ b/Ryujinx.HLE/HOS/Services/Time/Clock/StandardUserSystemClockCore.cs
@@ -8,22 +8,22 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
private StandardNetworkSystemClockCore _networkSystemClockCore;
private bool _autoCorrectionEnabled;
- private static StandardUserSystemClockCore instance;
+ private static StandardUserSystemClockCore _instance;
public static StandardUserSystemClockCore Instance
{
get
{
- if (instance == null)
+ if (_instance == null)
{
- instance = new StandardUserSystemClockCore(StandardLocalSystemClockCore.Instance, StandardNetworkSystemClockCore.Instance);
+ _instance = new StandardUserSystemClockCore(StandardLocalSystemClockCore.Instance, StandardNetworkSystemClockCore.Instance);
}
- return instance;
+ return _instance;
}
}
- public StandardUserSystemClockCore(StandardLocalSystemClockCore localSystemClockCore, StandardNetworkSystemClockCore networkSystemClockCore)
+ public StandardUserSystemClockCore(StandardLocalSystemClockCore localSystemClockCore, StandardNetworkSystemClockCore networkSystemClockCore) : base(localSystemClockCore.GetSteadyClockCore())
{
_localSystemClockCore = localSystemClockCore;
_networkSystemClockCore = networkSystemClockCore;
@@ -35,11 +35,6 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
return ResultCode.NotImplemented;
}
- public override SteadyClockCore GetSteadyClockCore()
- {
- return _localSystemClockCore.GetSteadyClockCore();
- }
-
public override ResultCode GetSystemClockContext(KThread thread, out SystemClockContext context)
{
ResultCode result = ApplyAutomaticCorrection(thread, false);
diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs
index e661ab53..54d9accf 100644
--- a/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs
+++ b/Ryujinx.HLE/HOS/Services/Time/Clock/SteadyClockCore.cs
@@ -1,54 +1,16 @@
using Ryujinx.HLE.HOS.Kernel.Threading;
-using Ryujinx.HLE.HOS.Services.Bpc;
using Ryujinx.HLE.Utilities;
using System;
namespace Ryujinx.HLE.HOS.Services.Time.Clock
{
- class SteadyClockCore
+ abstract class SteadyClockCore
{
- private long _setupValue;
- private ResultCode _setupResultCode;
- private bool _isRtcResetDetected;
- private TimeSpanType _testOffset;
- private TimeSpanType _internalOffset;
- private UInt128 _clockSourceId;
+ private UInt128 _clockSourceId;
- private static SteadyClockCore instance;
-
- public static SteadyClockCore Instance
- {
- get
- {
- if (instance == null)
- {
- instance = new SteadyClockCore();
- }
-
- return instance;
- }
- }
-
- private SteadyClockCore()
- {
- _testOffset = new TimeSpanType(0);
- _internalOffset = new TimeSpanType(0);
- _clockSourceId = new UInt128(Guid.NewGuid().ToByteArray());
- }
-
- private SteadyClockTimePoint GetTimePoint(KThread thread)
+ public SteadyClockCore()
{
- SteadyClockTimePoint result = new SteadyClockTimePoint
- {
- TimePoint = 0,
- ClockSourceId = _clockSourceId
- };
-
- TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(thread.Context.ThreadState.CntpctEl0, thread.Context.ThreadState.CntfrqEl0);
-
- result.TimePoint = _setupValue + ticksTimeSpan.ToSeconds();
-
- return result;
+ _clockSourceId = new UInt128(Guid.NewGuid().ToByteArray());
}
public UInt128 GetClockSourceId()
@@ -56,76 +18,45 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
return _clockSourceId;
}
- public SteadyClockTimePoint GetCurrentTimePoint(KThread thread)
- {
- SteadyClockTimePoint result = GetTimePoint(thread);
-
- result.TimePoint += _testOffset.ToSeconds();
- result.TimePoint += _internalOffset.ToSeconds();
-
- return result;
- }
-
- public TimeSpanType GetTestOffset()
+ public virtual TimeSpanType GetTestOffset()
{
- return _testOffset;
+ return new TimeSpanType(0);
}
- public void SetTestOffset(TimeSpanType testOffset)
- {
- _testOffset = testOffset;
- }
+ public virtual void SetTestOffset(TimeSpanType testOffset) {}
- public ResultCode GetRtcValue(out ulong rtcValue)
+ public virtual ResultCode GetRtcValue(out ulong rtcValue)
{
- return (ResultCode)IRtcManager.GetExternalRtcValue(out rtcValue);
- }
+ rtcValue = 0;
- public bool IsRtcResetDetected()
- {
- return _isRtcResetDetected;
+ return ResultCode.NotImplemented;
}
- public ResultCode GetSetupResultCode()
+ public virtual ResultCode GetSetupResultValue()
{
- return _setupResultCode;
+ return ResultCode.NotImplemented;
}
- public TimeSpanType GetInternalOffset()
+ public virtual TimeSpanType GetInternalOffset()
{
- return _internalOffset;
+ return new TimeSpanType(0);
}
- public void SetInternalOffset(TimeSpanType internalOffset)
- {
- _internalOffset = internalOffset;
- }
+ public virtual void SetInternalOffset(TimeSpanType internalOffset) {}
- public ResultCode GetSetupResultValue()
+ public virtual SteadyClockTimePoint GetTimePoint(KThread thread)
{
- return _setupResultCode;
+ throw new NotImplementedException();
}
- public void ConfigureSetupValue()
+ public SteadyClockTimePoint GetCurrentTimePoint(KThread thread)
{
- int retry = 0;
-
- ResultCode result = ResultCode.Success;
-
- while (retry < 20)
- {
- result = (ResultCode)IRtcManager.GetExternalRtcValue(out ulong rtcValue);
-
- if (result == ResultCode.Success)
- {
- _setupValue = (long)rtcValue;
- break;
- }
+ SteadyClockTimePoint result = GetTimePoint(thread);
- retry++;
- }
+ result.TimePoint += GetTestOffset().ToSeconds();
+ result.TimePoint += GetInternalOffset().ToSeconds();
- _setupResultCode = result;
+ return result;
}
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs
index d3a056e4..52f3c908 100644
--- a/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs
+++ b/Ryujinx.HLE/HOS/Services/Time/Clock/SystemClockCore.cs
@@ -4,11 +4,35 @@ namespace Ryujinx.HLE.HOS.Services.Time.Clock
{
abstract class SystemClockCore
{
- public abstract SteadyClockCore GetSteadyClockCore();
+ private SteadyClockCore _steadyClockCore;
+ private SystemClockContext _context;
- public abstract ResultCode GetSystemClockContext(KThread thread, out SystemClockContext context);
+ public SystemClockCore(SteadyClockCore steadyClockCore)
+ {
+ _steadyClockCore = steadyClockCore;
+ _context = new SystemClockContext();
+
+ _context.SteadyTimePoint.ClockSourceId = steadyClockCore.GetClockSourceId();
+ }
- public abstract ResultCode SetSystemClockContext(SystemClockContext context);
+ public virtual SteadyClockCore GetSteadyClockCore()
+ {
+ return _steadyClockCore;
+ }
+
+ public virtual ResultCode GetSystemClockContext(KThread thread, out SystemClockContext context)
+ {
+ context = _context;
+
+ return ResultCode.Success;
+ }
+
+ public virtual ResultCode SetSystemClockContext(SystemClockContext context)
+ {
+ _context = context;
+
+ return ResultCode.Success;
+ }
public abstract ResultCode Flush(SystemClockContext context);
diff --git a/Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs b/Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs
new file mode 100644
index 00000000..7a69b014
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Time/Clock/TickBasedSteadyClockCore.cs
@@ -0,0 +1,40 @@
+using Ryujinx.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
+
+namespace Ryujinx.HLE.HOS.Services.Time.Clock
+{
+ class TickBasedSteadyClockCore : SteadyClockCore
+ {
+ private static TickBasedSteadyClockCore _instance;
+
+ public static TickBasedSteadyClockCore Instance
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ _instance = new TickBasedSteadyClockCore();
+ }
+
+ return _instance;
+ }
+ }
+
+ private TickBasedSteadyClockCore() {}
+
+ public override SteadyClockTimePoint GetTimePoint(KThread thread)
+ {
+ SteadyClockTimePoint result = new SteadyClockTimePoint
+ {
+ TimePoint = 0,
+ ClockSourceId = GetClockSourceId()
+ };
+
+ TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(thread.Context.ThreadState.CntpctEl0, thread.Context.ThreadState.CntfrqEl0);
+
+ result.TimePoint = ticksTimeSpan.ToSeconds();
+
+ return result;
+ }
+ }
+}