Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time: Update for 15.0.0 changes and fixes long standing issues #4822

Merged
merged 6 commits into from
May 7, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Ryujinx.HLE/HOS/Horizon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,22 +222,22 @@ public Horizon(Switch device)
internalOffset = internalOffset.AddSeconds(-3600L);
}

internalOffset = new TimeSpanType(-internalOffset.NanoSeconds);
systemTime = new TimeSpanType(systemTime.NanoSeconds + internalOffset.NanoSeconds);

// First init the standard steady clock
TimeServiceManager.Instance.SetupStandardSteadyClock(TickSource, clockSourceId, systemTime, internalOffset, TimeSpanType.Zero, false);
TimeServiceManager.Instance.SetupStandardSteadyClock(TickSource, clockSourceId, TimeSpanType.Zero, TimeSpanType.Zero, TimeSpanType.Zero, false);
TimeServiceManager.Instance.SetupStandardLocalSystemClock(TickSource, new SystemClockContext(), systemTime.ToSeconds());
TimeServiceManager.Instance.StandardLocalSystemClock.GetClockContext(TickSource, out SystemClockContext localSytemClockContext);

if (NxSettings.Settings.TryGetValue("time!standard_network_clock_sufficient_accuracy_minutes", out object standardNetworkClockSufficientAccuracyMinutes))
{
TimeSpanType standardNetworkClockSufficientAccuracy = new TimeSpanType((int)standardNetworkClockSufficientAccuracyMinutes * 60000000000);

// The network system clock needs a valid system clock, as such we setup this system clock using the local system clock.
TimeServiceManager.Instance.StandardLocalSystemClock.GetClockContext(TickSource, out SystemClockContext localSytemClockContext);
TimeServiceManager.Instance.SetupStandardNetworkSystemClock(localSytemClockContext, standardNetworkClockSufficientAccuracy);
}

TimeServiceManager.Instance.SetupStandardUserSystemClock(TickSource, false, SteadyClockTimePoint.GetRandom());
TimeServiceManager.Instance.SetupStandardUserSystemClock(TickSource, false, localSytemClockContext.SteadyTimePoint);

// FIXME: TimeZone should be init here but it's actually done in ContentManager

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Runtime.InteropServices;

namespace Ryujinx.HLE.HOS.Services.Time.Clock.Types
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ContinuousAdjustmentTimePoint
{
public ulong ClockOffset;
public long Multiplier;
public long DivisorLog2;
public SystemClockContext Context;
}
}
53 changes: 37 additions & 16 deletions src/Ryujinx.HLE/HOS/Services/Time/TimeSharedMemory.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Ryujinx.Cpu;
using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Services.Time.Clock;
using Ryujinx.HLE.HOS.Services.Time.Clock.Types;
using Ryujinx.HLE.HOS.Services.Time.Types;
using Ryujinx.HLE.Utilities;
using System;
using System.Runtime.CompilerServices;
using System.Threading;
Expand All @@ -16,10 +16,11 @@ class TimeSharedMemory
private SharedMemoryStorage _timeSharedMemoryStorage;
private int _timeSharedMemorySize;

private const uint SteadyClockContextOffset = 0x00;
private const uint LocalSystemClockContextOffset = 0x38;
private const uint NetworkSystemClockContextOffset = 0x80;
private const uint SteadyClockContextOffset = 0x00;
private const uint LocalSystemClockContextOffset = 0x38;
private const uint NetworkSystemClockContextOffset = 0x80;
private const uint AutomaticCorrectionEnabledOffset = 0xC8;
private const uint ContinuousAdjustmentTimePointOffset = 0xD0;
marysaka marked this conversation as resolved.
Show resolved Hide resolved

public void Initialize(Switch device, KSharedMemory sharedMemory, SharedMemoryStorage timeSharedMemoryStorage, int timeSharedMemorySize)
{
Expand All @@ -39,15 +40,7 @@ public KSharedMemory GetSharedMemory()

public void SetupStandardSteadyClock(ITickSource tickSource, UInt128 clockSourceId, TimeSpanType currentTimePoint)
{
TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency);

SteadyClockContext context = new SteadyClockContext
{
InternalOffset = (ulong)(currentTimePoint.NanoSeconds - ticksTimeSpan.NanoSeconds),
ClockSourceId = clockSourceId
};

WriteObjectToSharedMemory(SteadyClockContextOffset, 4, context);
UpdateSteadyClock(tickSource, clockSourceId, currentTimePoint);
}

public void SetAutomaticCorrectionEnabled(bool isAutomaticCorrectionEnabled)
Expand All @@ -58,10 +51,38 @@ public void SetAutomaticCorrectionEnabled(bool isAutomaticCorrectionEnabled)

public void SetSteadyClockRawTimePoint(ITickSource tickSource, TimeSpanType currentTimePoint)
{
SteadyClockContext context = ReadObjectFromSharedMemory<SteadyClockContext>(SteadyClockContextOffset, 4);
TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency);
SteadyClockContext context = ReadObjectFromSharedMemory<SteadyClockContext>(SteadyClockContextOffset, 4);

context.InternalOffset = (ulong)(currentTimePoint.NanoSeconds - ticksTimeSpan.NanoSeconds);
UpdateSteadyClock(tickSource, context.ClockSourceId, currentTimePoint);
}

private void UpdateSteadyClock(ITickSource tickSource, UInt128 clockSourceId, TimeSpanType currentTimePoint)
{
TimeSpanType ticksTimeSpan = TimeSpanType.FromTicks(tickSource.Counter, tickSource.Frequency);

ContinuousAdjustmentTimePoint adjustmentTimePoint = new ContinuousAdjustmentTimePoint
{
ClockOffset = (ulong)ticksTimeSpan.NanoSeconds,
Multiplier = 1,
DivisorLog2 = 0,
Context = new SystemClockContext
{
Offset = 0,
SteadyTimePoint = new SteadyClockTimePoint
{
ClockSourceId = clockSourceId,
TimePoint = 0
}
}
};

WriteObjectToSharedMemory(ContinuousAdjustmentTimePointOffset, 4, adjustmentTimePoint);

SteadyClockContext context = new SteadyClockContext
{
InternalOffset = (ulong)(currentTimePoint.NanoSeconds - ticksTimeSpan.NanoSeconds),
ClockSourceId = clockSourceId
};

WriteObjectToSharedMemory(SteadyClockContextOffset, 4, context);
}
Expand Down