diff options
| author | Thomas Guillemard <me@thog.eu> | 2019-07-14 22:50:11 +0200 |
|---|---|---|
| committer | Ac_K <Acoustik666@gmail.com> | 2019-07-14 22:50:11 +0200 |
| commit | 97d0c6242368f443c50395b2fa9d99a59f1df1e8 (patch) | |
| tree | 95fe1df8cc70f578f4c595feca6d2c253e4ad366 /Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs | |
| parent | 4ad3936afd4ca393a05b330e3848958e9598e910 (diff) | |
Accurately implement steady & system clocks (#732)
* Improve SteadyClock implementation accuracy
* Rewrite system clocks to be accurate
* Implement IStaticService 100 & 101
* Add time:* permissions
* Address comments
* Realign TimePermissions definitions
* Address gdk's comments
* Fix after rebase
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs | 108 |
1 files changed, 59 insertions, 49 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs b/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs index 0ed34d17..ddd67a42 100644 --- a/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs +++ b/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs @@ -1,97 +1,107 @@ -using System; +using Ryujinx.Common; +using Ryujinx.HLE.HOS.Services.Time.Clock; namespace Ryujinx.HLE.HOS.Services.Time { class ISystemClock : IpcService { - private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + private SystemClockCore _clockCore; + private bool _writePermission; - private SystemClockType _clockType; - private DateTime _systemClockContextEpoch; - private long _systemClockTimePoint; - private byte[] _systemClockContextEnding; - private long _timeOffset; - - public ISystemClock(SystemClockType clockType) + public ISystemClock(SystemClockCore clockCore, bool writePermission) { - _clockType = clockType; - _systemClockContextEpoch = System.Diagnostics.Process.GetCurrentProcess().StartTime; - _systemClockContextEnding = new byte[0x10]; - _timeOffset = 0; - - if (clockType == SystemClockType.User || - clockType == SystemClockType.Network) - { - _systemClockContextEpoch = _systemClockContextEpoch.ToUniversalTime(); - } - - _systemClockTimePoint = (long)(_systemClockContextEpoch - Epoch).TotalSeconds; + _clockCore = clockCore; + _writePermission = writePermission; } [Command(0)] // GetCurrentTime() -> nn::time::PosixTime public ResultCode GetCurrentTime(ServiceCtx context) { - DateTime currentTime = DateTime.Now; + SteadyClockCore steadyClockCore = _clockCore.GetSteadyClockCore(); + SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(context.Thread); + + ResultCode result = _clockCore.GetSystemClockContext(context.Thread, out SystemClockContext clockContext); - if (_clockType == SystemClockType.User || - _clockType == SystemClockType.Network) + if (result == ResultCode.Success) { - currentTime = currentTime.ToUniversalTime(); - } + result = ResultCode.TimeMismatch; + + if (currentTimePoint.ClockSourceId == clockContext.SteadyTimePoint.ClockSourceId) + { + ulong posixTime = clockContext.Offset + currentTimePoint.TimePoint; + + context.ResponseData.Write(posixTime); - context.ResponseData.Write((long)((currentTime - Epoch).TotalSeconds) + _timeOffset); + result = 0; + } + } - return ResultCode.Success; + return result; } [Command(1)] // SetCurrentTime(nn::time::PosixTime) public ResultCode SetCurrentTime(ServiceCtx context) { - DateTime currentTime = DateTime.Now; - - if (_clockType == SystemClockType.User || - _clockType == SystemClockType.Network) + if (!_writePermission) { - currentTime = currentTime.ToUniversalTime(); + return ResultCode.PermissionDenied; } - _timeOffset = (context.RequestData.ReadInt64() - (long)(currentTime - Epoch).TotalSeconds); + ulong posixTime = context.RequestData.ReadUInt64(); + SteadyClockCore steadyClockCore = _clockCore.GetSteadyClockCore(); + SteadyClockTimePoint currentTimePoint = steadyClockCore.GetCurrentTimePoint(context.Thread); + + SystemClockContext clockContext = new SystemClockContext() + { + Offset = posixTime - currentTimePoint.TimePoint, + SteadyTimePoint = currentTimePoint + }; + + ResultCode result = _clockCore.SetSystemClockContext(clockContext); + + if (result == ResultCode.Success) + { + result = _clockCore.Flush(clockContext); + } - return ResultCode.Success; + return result; } [Command(2)] // GetSystemClockContext() -> nn::time::SystemClockContext public ResultCode GetSystemClockContext(ServiceCtx context) { - context.ResponseData.Write((long)(_systemClockContextEpoch - Epoch).TotalSeconds); - - // The point in time, TODO: is there a link between epoch and this? - context.ResponseData.Write(_systemClockTimePoint); + ResultCode result = _clockCore.GetSystemClockContext(context.Thread, out SystemClockContext clockContext); - // This seems to be some kind of identifier? - for (int i = 0; i < 0x10; i++) + if (result == ResultCode.Success) { - context.ResponseData.Write(_systemClockContextEnding[i]); + context.ResponseData.WriteStruct(clockContext); } - return ResultCode.Success; + return result; } [Command(3)] // SetSystemClockContext(nn::time::SystemClockContext) public ResultCode SetSystemClockContext(ServiceCtx context) { - long newSystemClockEpoch = context.RequestData.ReadInt64(); - long newSystemClockTimePoint = context.RequestData.ReadInt64(); + if (!_writePermission) + { + return ResultCode.PermissionDenied; + } + + SystemClockContext clockContext = context.RequestData.ReadStruct<SystemClockContext>(); - _systemClockContextEpoch = Epoch.Add(TimeSpan.FromSeconds(newSystemClockEpoch)); - _systemClockTimePoint = newSystemClockTimePoint; - _systemClockContextEnding = context.RequestData.ReadBytes(0x10); + ResultCode result = _clockCore.SetSystemClockContext(clockContext); + + if (result == ResultCode.Success) + { + result = _clockCore.Flush(clockContext); + } - return ResultCode.Success; + return result; } } }
\ No newline at end of file |
