Compare commits

..

4 Commits

Author SHA1 Message Date
Marco Carvalho
82f90704a0 Blocks should be synchronized on read-only fields (#5212)
* Blocks should be synchronized on read-only fields

* more readonlys

* fix alignment

* more

* Update ISelfController.cs

* simplify new

* simplify new
2023-06-15 00:34:55 +00:00
dependabot[bot]
f978d3726a nuget: bump System.Management from 7.0.1 to 7.0.2 (#5302)
Bumps [System.Management](https://github.com/dotnet/runtime) from 7.0.1 to 7.0.2.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v7.0.1...v7.0.2)

---
updated-dependencies:
- dependency-name: System.Management
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-14 18:21:17 +02:00
Mary
6f28c4abad test: Make tests runnable on system without 4KiB page size (#5184)
* ARMeilleure: Do not hardcode 4KiB page size in JitCache

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Memory.Tests

Fix running tests on Asahi Linux with 16KiB pages.

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Cpu

Fix running tests on Asahi Linux.

Test runner still crash when trying to run all test suite.

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Cpu

Fix somecrashes on Asahi Linux.

* test: Ignore Vshl test on ARM64 due to unicorn crashes

* test: Workaround hardcoded size on some tests

Change mapping of code and data in case of non 4KiB configuration.

* test: Make CpuTestT32Flow depends on code address

Fix failure with different page size.

* test: Disable CpuTestThumb.TestRandomTestCases when page size isn't 4KiB

The test data needs to be reevaluated to take different page size into account.

* Address gdkchan's comments
2023-06-14 18:02:41 +02:00
gdkchan
105c9712c1 Fix Arm32 double to int/uint conversion on Arm64 (#5292)
* Fix Arm32 double to int/uint conversion on Arm64

* PPTC version bump
2023-06-14 00:57:02 -03:00
56 changed files with 218 additions and 140 deletions

View File

@@ -46,7 +46,7 @@
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
<PackageVersion Include="System.Management" Version="7.0.1" />
<PackageVersion Include="System.Management" Version="7.0.2" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
</ItemGroup>

View File

@@ -165,7 +165,7 @@ namespace ARMeilleure.Instructions
{
Operand m = GetVecA32(op.Vm >> 1);
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, doubleSize);
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
Intrinsic inst = (unsigned ? Intrinsic.Arm64FcvtzuGp : Intrinsic.Arm64FcvtzsGp) | Intrinsic.Arm64VDouble;
@@ -175,7 +175,7 @@ namespace ARMeilleure.Instructions
}
else
{
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS);
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS, false);
}
}
else if (!roundWithFpscr && Optimizations.UseSse41)
@@ -260,28 +260,64 @@ namespace ARMeilleure.Instructions
if (Optimizations.UseAdvSimd)
{
if (unsigned)
bool doubleSize = floatSize == OperandType.FP64;
if (doubleSize)
{
inst = rm switch {
0b00 => Intrinsic.Arm64FcvtauS,
0b01 => Intrinsic.Arm64FcvtnuS,
0b10 => Intrinsic.Arm64FcvtpuS,
0b11 => Intrinsic.Arm64FcvtmuS,
_ => throw new ArgumentOutOfRangeException(nameof(rm))
};
Operand m = GetVecA32(op.Vm >> 1);
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
if (unsigned)
{
inst = rm switch {
0b00 => Intrinsic.Arm64FcvtauGp,
0b01 => Intrinsic.Arm64FcvtnuGp,
0b10 => Intrinsic.Arm64FcvtpuGp,
0b11 => Intrinsic.Arm64FcvtmuGp,
_ => throw new ArgumentOutOfRangeException(nameof(rm))
};
}
else
{
inst = rm switch {
0b00 => Intrinsic.Arm64FcvtasGp,
0b01 => Intrinsic.Arm64FcvtnsGp,
0b10 => Intrinsic.Arm64FcvtpsGp,
0b11 => Intrinsic.Arm64FcvtmsGp,
_ => throw new ArgumentOutOfRangeException(nameof(rm))
};
}
Operand asInteger = context.AddIntrinsicInt(inst | Intrinsic.Arm64VDouble, toConvert);
InsertScalar(context, op.Vd, asInteger);
}
else
{
inst = rm switch {
0b00 => Intrinsic.Arm64FcvtasS,
0b01 => Intrinsic.Arm64FcvtnsS,
0b10 => Intrinsic.Arm64FcvtpsS,
0b11 => Intrinsic.Arm64FcvtmsS,
_ => throw new ArgumentOutOfRangeException(nameof(rm))
};
}
if (unsigned)
{
inst = rm switch {
0b00 => Intrinsic.Arm64FcvtauS,
0b01 => Intrinsic.Arm64FcvtnuS,
0b10 => Intrinsic.Arm64FcvtpuS,
0b11 => Intrinsic.Arm64FcvtmuS,
_ => throw new ArgumentOutOfRangeException(nameof(rm))
};
}
else
{
inst = rm switch {
0b00 => Intrinsic.Arm64FcvtasS,
0b01 => Intrinsic.Arm64FcvtnsS,
0b10 => Intrinsic.Arm64FcvtpsS,
0b11 => Intrinsic.Arm64FcvtmsS,
_ => throw new ArgumentOutOfRangeException(nameof(rm))
};
}
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
}
}
else if (Optimizations.UseSse41)
{

View File

@@ -192,11 +192,10 @@ namespace ARMeilleure.Instructions
EmitVectorTernaryOpSimd32(context, (d, n, m) => context.AddIntrinsic(inst, d, n, m));
}
public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc)
public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc, bool doubleSize)
{
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
bool doubleSize = (op.Size & 1) != 0;
int shift = doubleSize ? 1 : 2;
Operand m = GetVecA32(op.Vm >> shift);
Operand d = GetVecA32(op.Vd >> shift);
@@ -215,8 +214,13 @@ namespace ARMeilleure.Instructions
{
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
inst |= ((op.Size & 1) != 0 ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128;
EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m));
EmitScalarUnaryOpF32(context, inst, (op.Size & 1) != 0);
}
public static void EmitScalarUnaryOpF32(ArmEmitterContext context, Intrinsic inst, bool doubleSize)
{
inst |= (doubleSize ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128;
EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m), doubleSize);
}
public static void EmitScalarBinaryOpSimd32(ArmEmitterContext context, Func2I scalarFunc)

View File

@@ -78,7 +78,7 @@ namespace ARMeilleure.Signal
private static IntPtr _signalHandlerPtr;
private static IntPtr _signalHandlerHandle;
private static readonly object _lock = new object();
private static readonly object _lock = new();
private static bool _initialized;
static NativeSignalHandler()

View File

@@ -2,6 +2,7 @@ using ARMeilleure.CodeGen;
using ARMeilleure.CodeGen.Unwinding;
using ARMeilleure.Memory;
using ARMeilleure.Native;
using Ryujinx.Memory;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -12,8 +13,8 @@ namespace ARMeilleure.Translation.Cache
{
static partial class JitCache
{
private const int PageSize = 4 * 1024;
private const int PageMask = PageSize - 1;
private static readonly int PageSize = (int)MemoryBlock.GetPageSize();
private static readonly int PageMask = PageSize - 1;
private const int CodeAlignment = 4; // Bytes.
private const int CacheSize = 2047 * 1024 * 1024;
@@ -25,7 +26,7 @@ namespace ARMeilleure.Translation.Cache
private static readonly List<CacheEntry> _cacheEntries = new List<CacheEntry>();
private static readonly object _lock = new object();
private static readonly object _lock = new();
private static bool _initialized;
[SupportedOSPlatform("windows")]

View File

@@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 5281; //! To be incremented manually for each change to the ARMeilleure project.
private const uint InternalVersion = 5292; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0";
private const string BackupDir = "1";

View File

@@ -17,7 +17,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
private Queue<OpenALAudioBuffer> _queuedBuffers;
private ulong _playedSampleCount;
private object _lock = new object();
private readonly object _lock = new();
public OpenALHardwareDeviceSession(OpenALHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
{

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Audio
/// <summary>
/// Lock used to control the waiters registration.
/// </summary>
private object _lock = new object();
private readonly object _lock = new();
/// <summary>
/// Events signaled when the driver played audio buffers.

View File

@@ -10,7 +10,7 @@ namespace Ryujinx.Audio.Backends.Common
{
private const int RingBufferAlignment = 2048;
private object _lock = new object();
private readonly object _lock = new();
private byte[] _buffer;
private int _size;

View File

@@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Input
/// </summary>
public class AudioInputManager : IDisposable
{
private object _lock = new object();
private readonly object _lock = new();
/// <summary>
/// Lock used for session allocation.
/// </summary>
private object _sessionLock = new object();
private readonly object _sessionLock = new();
/// <summary>
/// The session ids allocation table.

View File

@@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Input
/// <summary>
/// The lock of the parent.
/// </summary>
private object _parentLock;
private readonly object _parentLock;
/// <summary>
/// The dispose state.

View File

@@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Output
/// </summary>
public class AudioOutputManager : IDisposable
{
private object _lock = new object();
private readonly object _lock = new();
/// <summary>
/// Lock used for session allocation.
/// </summary>
private object _sessionLock = new object();
private readonly object _sessionLock = new();
/// <summary>
/// The session ids allocation table.

View File

@@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Output
/// <summary>
/// THe lock of the parent.
/// </summary>
private object _parentLock;
private readonly object _parentLock;
/// <summary>
/// The dispose state.

View File

@@ -26,7 +26,7 @@ namespace Ryujinx.Audio.Renderer.Server
{
public class AudioRenderSystem : IDisposable
{
private object _lock = new object();
private readonly object _lock = new();
private AudioRendererRenderingDevice _renderingDevice;
private AudioRendererExecutionMode _executionMode;

View File

@@ -19,12 +19,12 @@ namespace Ryujinx.Audio.Renderer.Server
/// <summary>
/// Lock used for session allocation.
/// </summary>
private object _sessionLock = new object();
private readonly object _sessionLock = new();
/// <summary>
/// Lock used to control the <see cref="AudioProcessor"/> running state.
/// </summary>
private object _audioProcessorLock = new object();
private readonly object _audioProcessorLock = new();
/// <summary>
/// The session ids allocation table.

View File

@@ -16,7 +16,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
/// <summary>
/// Global lock of the object.
/// </summary>
private object Lock = new object();
private readonly object Lock = new();
/// <summary>
/// The upsamplers instances.

View File

@@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
private int _refConsumerPtr;
private Action _interruptAction;
private object _interruptLock = new();
private readonly object _interruptLock = new();
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;

View File

@@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
private List<BufferMigration> _sources;
private BufferMigration _migrationTarget;
private object _lock = new object();
private readonly object _lock = new();
/// <summary>
/// Whether the modified range list has any entries or not.
@@ -125,7 +125,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
for (int i = 0; i < count; i++)
{
BufferModifiedRange overlap = overlaps[i];
if (overlap.Address > address)
{
// The start of the remaining region is uncovered by this overlap. Call the action for it.

View File

@@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private ulong _accumulatedCounter;
private int _waiterCount;
private object _lock = new object();
private readonly object _lock = new();
private Queue<BufferedQuery> _queryPool;
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);

View File

@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private bool _hostAccessReserved = false;
private int _refCount = 1; // Starts with a reference from the counter queue.
private object _lock = new object();
private readonly object _lock = new();
private ulong _result = ulong.MaxValue;
private double _divisor = 1f;

View File

@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.OpenGL
{
private const int DisposedLiveFrames = 2;
private readonly object _lock = new object();
private readonly object _lock = new();
private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new Dictionary<TextureCreateInfo, List<DisposedTexture>>();
/// <summary>

View File

@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private ulong _accumulatedCounter;
private int _waiterCount;
private object _lock = new object();
private readonly object _lock = new();
private Queue<BufferedQuery> _queryPool;
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private bool _hostAccessReserved = false;
private int _refCount = 1; // Starts with a reference from the counter queue.
private object _lock = new object();
private readonly object _lock = new();
private ulong _result = ulong.MaxValue;
private double _divisor = 1f;

View File

@@ -60,7 +60,7 @@ namespace Ryujinx.HLE.HOS.Applets
private bool _canAcceptController = false;
private KeyboardInputMode _inputMode = KeyboardInputMode.ControllerAndKeyboard;
private object _lock = new object();
private readonly object _lock = new();
public event EventHandler AppletStateChanged;

View File

@@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
private const int TextBoxBlinkSleepMilliseconds = 100;
private const int RendererWaitTimeoutMilliseconds = 100;
private readonly object _stateLock = new object();
private readonly object _stateLock = new();
private SoftwareKeyboardUiState _state = new SoftwareKeyboardUiState();
private SoftwareKeyboardRendererBase _renderer;

View File

@@ -26,7 +26,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
const string CancelText = "Cancel";
const string ControllerToggleText = "Toggle input";
private readonly object _bufferLock = new object();
private readonly object _bufferLock = new();
private RenderingSurfaceInfo _surfaceInfo = null;
private Image<Argb32> _surface = null;
@@ -311,7 +311,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
private static RectangleF MeasureString(ReadOnlySpan<char> text, Font font)
{
RendererOptions options = new RendererOptions(font);
if (text == "")
{
FontRectangle emptyRectangle = TextMeasurer.Measure(" ", options);

View File

@@ -26,8 +26,8 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
}
private TRef<bool> _cancelled = null;
private Thread _thread = null;
private object _lock = new object();
private Thread _thread = null;
private readonly object _lock = new();
public bool IsRunning
{

View File

@@ -40,8 +40,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public ProcessState State { get; private set; }
private object _processLock;
private object _threadingLock;
private readonly object _processLock = new();
private readonly object _threadingLock = new();
public KAddressArbiter AddressArbiter { get; private set; }
@@ -94,9 +94,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public KProcess(KernelContext context, bool allowCodeMemoryForJit = false) : base(context)
{
_processLock = new object();
_threadingLock = new object();
AddressArbiter = new KAddressArbiter(context);
_fullTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();

View File

@@ -112,7 +112,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
public bool WaitingInArbitration { get; set; }
private object _activityOperationLock;
private readonly object _activityOperationLock = new();
public KThread(KernelContext context) : base(context)
{
@@ -123,8 +123,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
_mutexWaiters = new LinkedList<KThread>();
_pinnedWaiters = new LinkedList<KThread>();
_activityOperationLock = new object();
}
public Result Initialize(

View File

@@ -17,8 +17,8 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
private KEvent _accumulatedSuspendedTickChangedEvent;
private int _accumulatedSuspendedTickChangedEventHandle;
private object _fatalSectionLock = new object();
private int _fatalSectionCount;
private readonly object _fatalSectionLock = new();
private int _fatalSectionCount;
// TODO: Set this when the game goes in suspension (go back to home menu ect), we currently don't support that so we can keep it set to 0.
private ulong _accumulatedSuspendedTickValue = 0;
@@ -429,4 +429,4 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
return ResultCode.Success;
}
}
}
}

View File

@@ -14,7 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator
private readonly UserId _userId;
private readonly FriendServicePermissionLevel _permissionLevel;
private readonly object _lock = new object();
private readonly object _lock = new();
private KEvent _notificationEvent;
private int _notificationEventHandle = 0;

View File

@@ -24,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
private NvFence _previousFailingFence;
private uint _failingCount;
public readonly object Lock = new object();
public readonly object Lock = new();
/// <summary>
/// Max failing count until waiting on CPU.

View File

@@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
private Switch _device;
private object _syncpointAllocatorLock = new object();
private readonly object _syncpointAllocatorLock = new();
public NvHostSyncpt(Switch device)
{

View File

@@ -10,7 +10,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
private static ConcurrentDictionary<ulong, BsdContext> _registry = new ConcurrentDictionary<ulong, BsdContext>();
private readonly object _lock = new object();
private readonly object _lock = new();
private List<IFileDescriptor> _fds;

View File

@@ -10,7 +10,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl
private ulong _value;
private readonly EventFdFlags _flags;
private object _lock = new object();
private readonly object _lock = new();
public bool Blocking { get => !_flags.HasFlag(EventFdFlags.NonBlocking); set => throw new NotSupportedException(); }

View File

@@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Services.Spl
{
private RandomNumberGenerator _rng;
private object _lock = new object();
private readonly object _lock = new();
public IRandomInterface(ServiceCtx context)
{

View File

@@ -40,13 +40,13 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
}
}
private VirtualFileSystem _virtualFileSystem;
private VirtualFileSystem _virtualFileSystem;
private IntegrityCheckLevel _fsIntegrityCheckLevel;
private ContentManager _contentManager;
private bool _initialized;
private ContentManager _contentManager;
private bool _initialized;
private Dictionary<CaCertificateId, CertStoreEntry> _certificates;
private object _lock = new object();
private readonly object _lock = new();
private struct CertStoreFileHeader
{

View File

@@ -34,7 +34,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
public bool EnableExternalEvent;
public int MaxBufferCountCached;
public readonly object Lock = new object();
public readonly object Lock = new();
private KEvent _waitBufferFreeEvent;
private KEvent _frameAvailableEvent;

View File

@@ -21,7 +21,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
private uint _currentCallbackTicket;
private uint _callbackTicket;
private readonly object _callbackLock = new object();
private readonly object _callbackLock = new();
public BufferQueueProducer(BufferQueueCore core, ITickSource tickSource)
{

View File

@@ -23,7 +23,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
protected BufferQueueConsumer Consumer;
protected readonly object Lock = new object();
protected readonly object Lock = new();
private IConsumerListener _listener;
@@ -168,7 +168,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
Slot slot = Slots[slotIndex];
// TODO: Check this. On Android, this checks the "handle". I assume NvMapHandle is the handle, but it might not be.
// TODO: Check this. On Android, this checks the "handle". I assume NvMapHandle is the handle, but it might not be.
return !slot.GraphicBuffer.IsNull && slot.GraphicBuffer.Object.Buffer.Surfaces[0].NvMapHandle == graphicBuffer.Object.Buffer.Surfaces[0].NvMapHandle;
}
}

View File

@@ -37,7 +37,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
private int _swapInterval;
private int _swapIntervalDelay;
private readonly object Lock = new object();
private readonly object Lock = new();
public long RenderLayerId { get; private set; }

View File

@@ -13,14 +13,13 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
private UInt128 _timeZoneRuleVersion;
private uint _totalLocationNameCount;
private SteadyClockTimePoint _timeZoneUpdateTimePoint;
private object _lock;
private readonly object _lock = new();
public TimeZoneManager()
{
_isInitialized = false;
_deviceLocationName = "UTC";
_timeZoneRuleVersion = new UInt128();
_lock = new object();
_myRules = new Box<TimeZoneRule>();
_timeZoneUpdateTimePoint = SteadyClockTimePoint.GetRandom();

View File

@@ -13,7 +13,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
private readonly List<MultiWaitHolderBase> _multiWaits;
private object _lock;
private readonly object _lock = new();
private int _waitingThreadHandle;
@@ -24,8 +24,6 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
public MultiWaitImpl()
{
_multiWaits = new List<MultiWaitHolderBase>();
_lock = new object();
}
public void LinkMultiWaitHolder(MultiWaitHolderBase multiWaitHolder)

View File

@@ -46,7 +46,7 @@ namespace Ryujinx.Input.SDL2
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_PADDLE2,
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_PADDLE3,
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_PADDLE4,
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_TOUCHPAD,
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_TOUCHPAD,
// Virtual buttons are invalid, ignored.
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_INVALID,
@@ -55,7 +55,7 @@ namespace Ryujinx.Input.SDL2
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_INVALID,
};
private object _userMappingLock = new object();
private readonly object _userMappingLock = new();
private List<ButtonMappingEntry> _buttonsUserMapping;

View File

@@ -24,7 +24,7 @@ namespace Ryujinx.Input.SDL2
}
}
private object _userMappingLock = new object();
private readonly object _userMappingLock = new();
private readonly SDL2KeyboardDriver _driver;
private StandardKeyboardInputConfig _configuration;

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Input.HLE
{
private CemuHookClient _cemuHookClient;
private object _lock = new object();
private readonly object _lock = new();
private bool _blockInputUpdates;
@@ -271,7 +271,7 @@ namespace Ryujinx.Input.HLE
_device.Hid.Mouse.Update((int)position.X, (int)position.Y, buttons, (int)mouseInput.Scroll.X, (int)mouseInput.Scroll.Y, true);
}
else
else
{
_device.Hid.Mouse.Update(0, 0);
}

View File

@@ -52,7 +52,7 @@ namespace Ryujinx.Memory.Tracking
private event Action _onDirty;
private object _preActionLock = new object();
private readonly object _preActionLock = new();
private RegionSignal _preAction; // Action to perform before a read or write. This will block the memory access.
private PreciseRegionSignal _preciseAction; // Action to perform on a precise read or write.
private readonly List<VirtualRegion> _regions;

View File

@@ -41,7 +41,7 @@ namespace Ryujinx.SDL2.Common
private ConcurrentDictionary<uint, Action<SDL_Event>> _registeredWindowHandlers;
private object _lock = new object();
private readonly object _lock = new();
private SDL2Driver() {}

View File

@@ -7,7 +7,7 @@ namespace Ryujinx.Tests.Memory
{
public class Tests
{
private const ulong MemorySize = 0x8000;
private static readonly ulong MemorySize = MemoryBlock.GetPageSize() * 8;
private MemoryBlock _memoryBlock;
@@ -44,14 +44,17 @@ namespace Ryujinx.Tests.Memory
[Platform(Exclude = "MacOsX")]
public void Test_Alias()
{
using MemoryBlock backing = new MemoryBlock(0x10000, MemoryAllocationFlags.Mirrorable);
using MemoryBlock toAlias = new MemoryBlock(0x10000, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
ulong pageSize = MemoryBlock.GetPageSize();
ulong blockSize = MemoryBlock.GetPageSize() * 16;
toAlias.MapView(backing, 0x1000, 0, 0x4000);
toAlias.UnmapView(backing, 0x3000, 0x1000);
using MemoryBlock backing = new MemoryBlock(blockSize, MemoryAllocationFlags.Mirrorable);
using MemoryBlock toAlias = new MemoryBlock(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
toAlias.MapView(backing, pageSize, 0, pageSize * 4);
toAlias.UnmapView(backing, pageSize * 3, pageSize);
toAlias.Write(0, 0xbadc0de);
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, 0x1000), 0xbadc0de);
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (int)pageSize), 0xbadc0de);
}
[Test]
@@ -59,8 +62,12 @@ namespace Ryujinx.Tests.Memory
[Platform(Exclude = "MacOsX")]
public void Test_AliasRandom()
{
using MemoryBlock backing = new MemoryBlock(0x80000, MemoryAllocationFlags.Mirrorable);
using MemoryBlock toAlias = new MemoryBlock(0x80000, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
ulong pageSize = MemoryBlock.GetPageSize();
int pageBits = (int)ulong.Log2(pageSize);
ulong blockSize = MemoryBlock.GetPageSize() * 128;
using MemoryBlock backing = new MemoryBlock(blockSize, MemoryAllocationFlags.Mirrorable);
using MemoryBlock toAlias = new MemoryBlock(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
Random rng = new Random(123);
@@ -72,16 +79,16 @@ namespace Ryujinx.Tests.Memory
if ((rng.Next() & 1) != 0)
{
toAlias.MapView(backing, (ulong)srcPage << 12, (ulong)dstPage << 12, (ulong)pages << 12);
toAlias.MapView(backing, (ulong)srcPage << pageBits, (ulong)dstPage << pageBits, (ulong)pages << pageBits);
int offset = rng.Next(0, 0x1000 - sizeof(int));
int offset = rng.Next(0, (int)pageSize - sizeof(int));
toAlias.Write((ulong)((dstPage << 12) + offset), 0xbadc0de);
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << 12) + offset), 0xbadc0de);
toAlias.Write((ulong)((dstPage << pageBits) + offset), 0xbadc0de);
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << pageBits) + offset), 0xbadc0de);
}
else
{
toAlias.UnmapView(backing, (ulong)dstPage << 12, (ulong)pages << 12);
toAlias.UnmapView(backing, (ulong)dstPage << pageBits, (ulong)pages << pageBits);
}
}
}
@@ -91,7 +98,7 @@ namespace Ryujinx.Tests.Memory
[Platform(Exclude = "MacOsX")]
public void Test_AliasMapLeak()
{
ulong pageSize = 4096;
ulong pageSize = MemoryBlock.GetPageSize();
ulong size = 100000 * pageSize; // The mappings limit on Linux is usually around 65K, so let's make sure we are above that.
using MemoryBlock backing = new MemoryBlock(pageSize, MemoryAllocationFlags.Mirrorable);

View File

@@ -13,9 +13,9 @@ namespace Ryujinx.Tests.Cpu
[TestFixture]
public class CpuTest
{
protected const ulong Size = 0x1000;
protected const ulong CodeBaseAddress = 0x1000;
protected const ulong DataBaseAddress = CodeBaseAddress + Size;
protected static readonly ulong Size = MemoryBlock.GetPageSize();
protected static ulong CodeBaseAddress = Size;
protected static ulong DataBaseAddress = CodeBaseAddress + Size;
private static bool Ignore_FpcrFz = false;
private static bool Ignore_FpcrDn = false;
@@ -39,12 +39,24 @@ namespace Ryujinx.Tests.Cpu
[SetUp]
public void Setup()
{
_currAddress = CodeBaseAddress;
int pageBits = (int)ulong.Log2(Size);
_ram = new MemoryBlock(Size * 2);
_memory = new MemoryManager(_ram, 1ul << 16);
_memory = new MemoryManager(_ram, 1ul << (pageBits + 4));
_memory.IncrementReferenceCount();
_memory.Map(CodeBaseAddress, 0, Size * 2, MemoryMapFlags.Private);
// Some tests depends on hardcoded address that were computed for 4KiB.
// We change the layout on non 4KiB platforms to keep compat here.
if (Size > 0x1000)
{
DataBaseAddress = 0;
CodeBaseAddress = Size;
}
_currAddress = CodeBaseAddress;
_memory.Map(CodeBaseAddress, 0, Size, MemoryMapFlags.Private);
_memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private);
_context = CpuContext.CreateExecutionContext();
Translator.IsReadyForTranslation.Set();

View File

@@ -13,9 +13,9 @@ namespace Ryujinx.Tests.Cpu
[TestFixture]
public class CpuTest32
{
protected const uint Size = 0x1000;
protected const uint CodeBaseAddress = 0x1000;
protected const uint DataBaseAddress = CodeBaseAddress + Size;
protected static readonly uint Size = (uint)MemoryBlock.GetPageSize();
protected static uint CodeBaseAddress = Size;
protected static uint DataBaseAddress = CodeBaseAddress + Size;
private uint _currAddress;
@@ -33,12 +33,24 @@ namespace Ryujinx.Tests.Cpu
[SetUp]
public void Setup()
{
_currAddress = CodeBaseAddress;
int pageBits = (int)ulong.Log2(Size);
_ram = new MemoryBlock(Size * 2);
_memory = new MemoryManager(_ram, 1ul << 16);
_memory = new MemoryManager(_ram, 1ul << (pageBits + 4));
_memory.IncrementReferenceCount();
_memory.Map(CodeBaseAddress, 0, Size * 2, MemoryMapFlags.Private);
// Some tests depends on hardcoded address that were computed for 4KiB.
// We change the layout on non 4KiB platforms to keep compat here.
if (Size > 0x1000)
{
DataBaseAddress = 0;
CodeBaseAddress = Size;
}
_currAddress = CodeBaseAddress;
_memory.Map(CodeBaseAddress, 0, Size, MemoryMapFlags.Private);
_memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private);
_context = CpuContext.CreateExecutionContext();
_context.IsAarch32 = true;

View File

@@ -1,6 +1,7 @@
#define SimdMemory32
using ARMeilleure.State;
using Ryujinx.Memory;
using NUnit.Framework;
using System;
@@ -9,6 +10,7 @@ namespace Ryujinx.Tests.Cpu
[Category("SimdMemory32")]
public sealed class CpuTestSimdMemory32 : CpuTest32
{
private static readonly uint TestOffset = DataBaseAddress + 0x500;
#if SimdMemory32
private uint[] _ldStModes =
@@ -42,7 +44,7 @@ namespace Ryujinx.Tests.Cpu
[Range(0u, 3u)] uint n,
[Values(0x0u)] uint offset)
{
var data = GenerateVectorSequence(0x1000);
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data);
uint opcode = 0xf4a00000u; // VLD1.8 {D0[0]}, [R0], R0
@@ -58,7 +60,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500);
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
CompareAgainstUnicorn();
}
@@ -72,7 +74,7 @@ namespace Ryujinx.Tests.Cpu
[Values] bool t,
[Values(0x0u)] uint offset)
{
var data = GenerateVectorSequence(0x1000);
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data);
uint opcode = 0xf4a00c00u; // VLD1.8 {D0[0]}, [R0], R0
@@ -85,7 +87,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
if (t) opcode |= 1 << 5;
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500);
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
CompareAgainstUnicorn();
}
@@ -98,7 +100,7 @@ namespace Ryujinx.Tests.Cpu
[Range(0u, 10u)] uint mode,
[Values(0x0u)] uint offset)
{
var data = GenerateVectorSequence(0x1000);
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data);
uint opcode = 0xf4200000u; // VLD4.8 {D0, D1, D2, D3}, [R0], R0
@@ -114,7 +116,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12);
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500);
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
CompareAgainstUnicorn();
}
@@ -128,7 +130,7 @@ namespace Ryujinx.Tests.Cpu
[Range(0u, 3u)] uint n,
[Values(0x0u)] uint offset)
{
var data = GenerateVectorSequence(0x1000);
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data);
(V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors();
@@ -146,7 +148,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= (n & 3) << 8; // ST1 is 0, ST2 is 1 etc.
SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500);
SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset);
CompareAgainstUnicorn();
}
@@ -159,7 +161,7 @@ namespace Ryujinx.Tests.Cpu
[Range(0u, 10u)] uint mode,
[Values(0x0u)] uint offset)
{
var data = GenerateVectorSequence(0x1000);
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data);
(V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors();
@@ -177,7 +179,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12);
SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500);
SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset);
CompareAgainstUnicorn();
}
@@ -189,7 +191,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0x1u, 0x32u)] uint regs,
[Values] bool single)
{
var data = GenerateVectorSequence(0x1000);
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data);
uint opcode = 0xec100a00u; // VST4.8 {D0, D1, D2, D3}, [R0], R0
@@ -225,7 +227,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= regs & 0xff;
SingleOpcode(opcode, r0: 0x2500, sp: 0x2500);
SingleOpcode(opcode, r0: TestOffset, sp: TestOffset);
CompareAgainstUnicorn();
}
@@ -237,7 +239,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0x0u)] uint imm,
[Values] bool sub)
{
var data = GenerateVectorSequence(0x1000);
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data);
uint opcode = 0xed900a00u; // VLDR.32 S0, [R0, #0]
@@ -260,7 +262,7 @@ namespace Ryujinx.Tests.Cpu
}
opcode |= imm & 0xff;
SingleOpcode(opcode, r0: 0x2500);
SingleOpcode(opcode, r0: TestOffset);
CompareAgainstUnicorn();
}
@@ -272,7 +274,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0x0u)] uint imm,
[Values] bool sub)
{
var data = GenerateVectorSequence(0x1000);
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data);
uint opcode = 0xed800a00u; // VSTR.32 S0, [R0, #0]
@@ -297,7 +299,7 @@ namespace Ryujinx.Tests.Cpu
(V128 vec1, V128 vec2, _, _) = GenerateTestVectors();
SingleOpcode(opcode, r0: 0x2500, v0: vec1, v1: vec2);
SingleOpcode(opcode, r0: TestOffset, v0: vec1, v1: vec2);
CompareAgainstUnicorn();
}

View File

@@ -3,6 +3,7 @@
using ARMeilleure.State;
using NUnit.Framework;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Ryujinx.Tests.Cpu
{
@@ -703,6 +704,11 @@ namespace Ryujinx.Tests.Cpu
[Values] bool q,
[Values] bool u)
{
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{
Assert.Ignore("Unicorn on ARM64 crash while executing this test");
}
uint opcode = 0xf2000400u; // VSHL.S8 D0, D0, D0
if (q)
{

View File

@@ -109,7 +109,7 @@ namespace Ryujinx.Tests.Cpu
ExecuteOpcodes(runUnicorn: false);
Assert.That(GetContext().GetX(0), Is.EqualTo(0x1005));
Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x5));
}
[Test]
@@ -133,7 +133,7 @@ namespace Ryujinx.Tests.Cpu
ExecuteOpcodes(runUnicorn: false);
Assert.That(GetContext().GetX(0), Is.EqualTo(0x1005));
Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x5));
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
}
@@ -160,7 +160,7 @@ namespace Ryujinx.Tests.Cpu
ExecuteOpcodes(runUnicorn: false);
Assert.That(GetContext().GetX(0), Is.EqualTo(0x1007));
Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x7));
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
}
}

View File

@@ -268,6 +268,12 @@ namespace Ryujinx.Tests.Cpu
[Test]
public void TestRandomTestCases([ValueSource(nameof(RandomTestCases))] PrecomputedThumbTestCase test)
{
if (Size != 0x1000)
{
// TODO: Change it to depend on DataBaseAddress instead.
Assert.Ignore("This test currently only support 4KiB page size");
}
RunPrecomputedTestCase(test);
}

View File

@@ -21,7 +21,7 @@ namespace Ryujinx.Input.GTK3
}
}
private object _userMappingLock = new object();
private readonly object _userMappingLock = new();
private readonly GTK3KeyboardDriver _driver;
private StandardKeyboardInputConfig _configuration;