Thread scheduler rewrite (#393)

* Started to rewrite the thread scheduler

* Add a single core-like scheduling mode, enabled by default

* Clear exclusive monitor on context switch

* Add SetThreadActivity, misc fixes

* Implement WaitForAddress and SignalToAddress svcs, misc fixes

* Misc fixes (on SetActivity and Arbiter), other tweaks

* Rebased

* Add missing null check

* Rename multicore key on config, fix UpdatePriorityInheritance

* Make scheduling data MLQs private

* nit: Ordering
This commit is contained in:
gdkchan 2018-09-18 20:36:43 -03:00 committed by GitHub
parent 33e2810ef3
commit b8133c1997
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 3262 additions and 1540 deletions

View file

@ -26,14 +26,14 @@ namespace Ryujinx.HLE.HOS.Services.Am
public long GetCommonStateGetter(ServiceCtx Context)
{
MakeObject(Context, new ICommonStateGetter());
MakeObject(Context, new ICommonStateGetter(Context.Device.System));
return 0;
}
public long GetSelfController(ServiceCtx Context)
{
MakeObject(Context, new ISelfController());
MakeObject(Context, new ISelfController(Context.Device.System));
return 0;
}

View file

@ -15,7 +15,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
private KEvent DisplayResolutionChangeEvent;
public ICommonStateGetter()
public ICommonStateGetter(Horizon System)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -29,7 +29,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
{ 61, GetDefaultDisplayResolutionChangeEvent }
};
DisplayResolutionChangeEvent = new KEvent();
DisplayResolutionChangeEvent = new KEvent(System);
}
public long GetEventHandle(ServiceCtx Context)

View file

@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
private KEvent ChannelEvent;
public IHomeMenuFunctions()
public IHomeMenuFunctions(Horizon System)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
};
//ToDo: Signal this Event somewhere in future.
ChannelEvent = new KEvent();
ChannelEvent = new KEvent(System);
}
public long RequestToGetForeground(ServiceCtx Context)

View file

@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
private KEvent StateChangedEvent;
public ILibraryAppletAccessor()
public ILibraryAppletAccessor(Horizon System)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -24,12 +24,12 @@ namespace Ryujinx.HLE.HOS.Services.Am
{ 101, PopOutData }
};
StateChangedEvent = new KEvent();
StateChangedEvent = new KEvent(System);
}
public long GetAppletStateChangedEvent(ServiceCtx Context)
{
StateChangedEvent.WaitEvent.Set();
StateChangedEvent.Signal();
int Handle = Context.Process.HandleTable.OpenHandle(StateChangedEvent);

View file

@ -20,7 +20,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
public long CreateLibraryApplet(ServiceCtx Context)
{
MakeObject(Context, new ILibraryAppletAccessor());
MakeObject(Context, new ILibraryAppletAccessor(Context.Device.System));
return 0;
}

View file

@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
private KEvent LaunchableEvent;
public ISelfController()
public ISelfController(Horizon System)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -31,7 +31,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
{ 50, SetHandlesRequestToDisplay }
};
LaunchableEvent = new KEvent();
LaunchableEvent = new KEvent(System);
}
public long Exit(ServiceCtx Context)
@ -57,7 +57,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
public long GetLibraryAppletLaunchableEvent(ServiceCtx Context)
{
LaunchableEvent.WaitEvent.Set();
LaunchableEvent.Signal();
int Handle = Context.Process.HandleTable.OpenHandle(LaunchableEvent);

View file

@ -28,14 +28,14 @@ namespace Ryujinx.HLE.HOS.Services.Am
public long GetCommonStateGetter(ServiceCtx Context)
{
MakeObject(Context, new ICommonStateGetter());
MakeObject(Context, new ICommonStateGetter(Context.Device.System));
return 0;
}
public long GetSelfController(ServiceCtx Context)
{
MakeObject(Context, new ISelfController());
MakeObject(Context, new ISelfController(Context.Device.System));
return 0;
}
@ -70,7 +70,7 @@ namespace Ryujinx.HLE.HOS.Services.Am
public long GetHomeMenuFunctions(ServiceCtx Context)
{
MakeObject(Context, new IHomeMenuFunctions());
MakeObject(Context, new IHomeMenuFunctions(Context.Device.System));
return 0;
}

View file

@ -155,8 +155,6 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
if (Disposing)
{
AudioOut.CloseTrack(Track);
ReleaseEvent.Dispose();
}
}
}

View file

@ -38,7 +38,11 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
private int Track;
public IAudioRenderer(AMemory Memory, IAalOutput AudioOut, AudioRendererParameter Params)
public IAudioRenderer(
Horizon System,
AMemory Memory,
IAalOutput AudioOut,
AudioRendererParameter Params)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -48,7 +52,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
{ 7, QuerySystemEvent }
};
UpdateEvent = new KEvent();
UpdateEvent = new KEvent(System);
this.Memory = Memory;
this.AudioOut = AudioOut;
@ -68,7 +72,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
private void AudioCallback()
{
UpdateEvent.WaitEvent.Set();
UpdateEvent.Signal();
}
private static T[] CreateArray<T>(int Size) where T : new()
@ -310,8 +314,6 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
if (Disposing)
{
AudioOut.CloseTrack(Track);
UpdateEvent.Dispose();
}
}
}

View file

@ -15,7 +15,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud
private KEvent SystemEvent;
public IAudioDevice()
public IAudioDevice(Horizon System)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -32,10 +32,10 @@ namespace Ryujinx.HLE.HOS.Services.Aud
{ 12, QueryAudioDeviceOutputEvent }
};
SystemEvent = new KEvent();
SystemEvent = new KEvent(System);
//TODO: We shouldn't be signaling this here.
SystemEvent.WaitEvent.Set();
SystemEvent.Signal();
}
public long ListAudioDeviceName(ServiceCtx Context)

View file

@ -146,11 +146,11 @@ namespace Ryujinx.HLE.HOS.Services.Aud
Channels = DefaultChannelsCount;
}
KEvent ReleaseEvent = new KEvent();
KEvent ReleaseEvent = new KEvent(Context.Device.System);
ReleaseCallback Callback = () =>
{
ReleaseEvent.WaitEvent.Set();
ReleaseEvent.Signal();
};
IAalOutput AudioOut = Context.Device.AudioOut;

View file

@ -40,7 +40,11 @@ namespace Ryujinx.HLE.HOS.Services.Aud
AudioRendererParameter Params = GetAudioRendererParameter(Context);
MakeObject(Context, new IAudioRenderer(Context.Memory, AudioOut, Params));
MakeObject(Context, new IAudioRenderer(
Context.Device.System,
Context.Memory,
AudioOut,
Params));
return 0;
}
@ -161,7 +165,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud
{
long UserId = Context.RequestData.ReadInt64();
MakeObject(Context, new IAudioDevice());
MakeObject(Context, new IAudioDevice(Context.Device.System));
return 0;
}

View file

@ -2,12 +2,11 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.Input;
using Ryujinx.HLE.Logging;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Hid
{
class IHidServer : IpcService, IDisposable
class IHidServer : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
@ -15,7 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public IHidServer()
public IHidServer(Horizon System)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -45,7 +44,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{ 206, SendVibrationValues }
};
NpadStyleSetUpdateEvent = new KEvent();
NpadStyleSetUpdateEvent = new KEvent(System);
}
public long CreateAppletResource(ServiceCtx Context)
@ -282,18 +281,5 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return 0;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
NpadStyleSetUpdateEvent.Dispose();
}
}
}
}

View file

@ -24,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfp
private KEvent AvailabilityChangeEvent;
public IUser()
public IUser(Horizon System)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -37,9 +37,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfp
{ 23, AttachAvailabilityChangeEvent }
};
ActivateEvent = new KEvent();
DeactivateEvent = new KEvent();
AvailabilityChangeEvent = new KEvent();
ActivateEvent = new KEvent(System);
DeactivateEvent = new KEvent(System);
AvailabilityChangeEvent = new KEvent(System);
}
public long Initialize(ServiceCtx Context)

View file

@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfp
public long GetUserInterface(ServiceCtx Context)
{
MakeObject(Context, new IUser());
MakeObject(Context, new IUser(Context.Device.System));
return 0;
}

View file

@ -30,7 +30,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
{
int Unknown = Context.RequestData.ReadInt32();
MakeObject(Context, new IRequest());
MakeObject(Context, new IRequest(Context.Device.System));
Context.Device.Log.PrintStub(LogClass.ServiceNifm, "Stubbed.");

View file

@ -1,12 +1,11 @@
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.Logging;
using System;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Nifm
{
class IRequest : IpcService, IDisposable
class IRequest : IpcService
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
@ -15,7 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
private KEvent Event0;
private KEvent Event1;
public IRequest()
public IRequest(Horizon System)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -27,8 +26,8 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
{ 11, SetConnectionConfirmationOption }
};
Event0 = new KEvent();
Event1 = new KEvent();
Event0 = new KEvent(System);
Event1 = new KEvent(System);
}
public long GetRequestState(ServiceCtx Context)
@ -77,19 +76,5 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
return 0;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
Event0.Dispose();
Event1.Dispose();
}
}
}
}

View file

@ -12,7 +12,7 @@ using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Nv
{
class INvDrvServices : IpcService, IDisposable
class INvDrvServices : IpcService
{
private delegate int IoctlProcessor(ServiceCtx Context, int Cmd);
@ -34,7 +34,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
private KEvent Event;
public INvDrvServices()
public INvDrvServices(Horizon System)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -48,7 +48,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
{ 13, FinishInitialize }
};
Event = new KEvent();
Event = new KEvent(System);
}
static INvDrvServices()
@ -214,18 +214,5 @@ namespace Ryujinx.HLE.HOS.Services.Nv
NvMapIoctl.UnloadProcess(Process);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
Event.Dispose();
}
}
}
}

View file

@ -26,7 +26,7 @@ namespace Ryujinx.HLE.HOS.Services
{
static class ServiceFactory
{
public static IpcService MakeService(string Name)
public static IpcService MakeService(Horizon System, string Name)
{
switch (Name)
{
@ -94,7 +94,7 @@ namespace Ryujinx.HLE.HOS.Services
return new IFileSystemProxy();
case "hid":
return new IHidServer();
return new IHidServer(System);
case "lm":
return new ILogService();
@ -118,10 +118,10 @@ namespace Ryujinx.HLE.HOS.Services
return new IVulnerabilityManagerInterface();
case "nvdrv":
return new INvDrvServices();
return new INvDrvServices(System);
case "nvdrv:a":
return new INvDrvServices();
return new INvDrvServices(System);
case "pctl:s":
return new IParentalControlServiceFactory();

View file

@ -57,7 +57,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm
return 0;
}
KSession Session = new KSession(ServiceFactory.MakeService(Name), Name);
KSession Session = new KSession(ServiceFactory.MakeService(Context.Device.System, Name), Name);
int Handle = Context.Process.HandleTable.OpenHandle(Session);

View file

@ -41,7 +41,9 @@ namespace Ryujinx.HLE.HOS.Services.Vi
public long GetRelayService(ServiceCtx Context)
{
MakeObject(Context, new IHOSBinderDriver(Context.Device.Gpu.Renderer));
MakeObject(Context, new IHOSBinderDriver(
Context.Device.System,
Context.Device.Gpu.Renderer));
return 0;
}
@ -62,7 +64,9 @@ namespace Ryujinx.HLE.HOS.Services.Vi
public long GetIndirectDisplayTransactionService(ServiceCtx Context)
{
MakeObject(Context, new IHOSBinderDriver(Context.Device.Gpu.Renderer));
MakeObject(Context, new IHOSBinderDriver(
Context.Device.System,
Context.Device.Gpu.Renderer));
return 0;
}

View file

@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
private NvFlinger Flinger;
public IHOSBinderDriver(IGalRenderer Renderer)
public IHOSBinderDriver(Horizon System, IGalRenderer Renderer)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
@ -27,9 +27,9 @@ namespace Ryujinx.HLE.HOS.Services.Vi
{ 3, TransactParcelAuto }
};
BinderEvent = new KEvent();
BinderEvent = new KEvent(System);
BinderEvent.WaitEvent.Set();
BinderEvent.Signal();
Flinger = new NvFlinger(Renderer, BinderEvent);
}
@ -93,8 +93,6 @@ namespace Ryujinx.HLE.HOS.Services.Vi
{
if (Disposing)
{
BinderEvent.Dispose();
Flinger.Dispose();
}
}

View file

@ -64,7 +64,7 @@ namespace Ryujinx.HLE.HOS.Services.Android
private BufferEntry[] BufferQueue;
private ManualResetEvent WaitBufferFree;
private AutoResetEvent WaitBufferFree;
private bool Disposed;
@ -88,7 +88,7 @@ namespace Ryujinx.HLE.HOS.Services.Android
BufferQueue = new BufferEntry[0x40];
WaitBufferFree = new ManualResetEvent(false);
WaitBufferFree = new AutoResetEvent(false);
}
public long ProcessParcelRequest(ServiceCtx Context, byte[] ParcelData, int Code)
@ -220,6 +220,8 @@ namespace Ryujinx.HLE.HOS.Services.Android
BufferQueue[Slot].State = BufferState.Free;
WaitBufferFree.Set();
return MakeReplyParcel(Context, 0);
}
@ -336,12 +338,9 @@ namespace Ryujinx.HLE.HOS.Services.Android
{
BufferQueue[Slot].State = BufferState.Free;
BinderEvent.WaitEvent.Set();
BinderEvent.Signal();
lock (WaitBufferFree)
{
WaitBufferFree.Set();
}
WaitBufferFree.Set();
}
private int GetFreeSlotBlocking(int Width, int Height)
@ -350,19 +349,14 @@ namespace Ryujinx.HLE.HOS.Services.Android
do
{
lock (WaitBufferFree)
if ((Slot = GetFreeSlot(Width, Height)) != -1)
{
if ((Slot = GetFreeSlot(Width, Height)) != -1)
{
break;
}
break;
}
if (Disposed)
{
break;
}
WaitBufferFree.Reset();
if (Disposed)
{
break;
}
WaitBufferFree.WaitOne();
@ -409,11 +403,7 @@ namespace Ryujinx.HLE.HOS.Services.Android
{
Disposed = true;
lock (WaitBufferFree)
{
WaitBufferFree.Set();
}
WaitBufferFree.Set();
WaitBufferFree.Dispose();
}
}