* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0052 warnings * Address dotnet format CA1816 warnings * Address or silence dotnet format CA1069 warnings * Address remaining dotnet format analyzer warnings * Address review comments * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Revert formatting changes for while and for-loops * Another rebase, another dotnet format run * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format analyzers after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Start working on disabled warnings * Address IDE0251 warnings * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Address review feedback * Add trailing commas * Remove SuppressMessage for IDE0066 * Make explicit Equals implementation implicit
107 lines
3.1 KiB
C#
107 lines
3.1 KiB
C#
using Ryujinx.Graphics.GAL.Multithreading.Resources.Programs;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
|
|
namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
|
{
|
|
/// <summary>
|
|
/// A structure handling multithreaded compilation for programs.
|
|
/// </summary>
|
|
class ProgramQueue
|
|
{
|
|
private const int MaxConcurrentCompilations = 8;
|
|
|
|
private readonly IRenderer _renderer;
|
|
|
|
private readonly Queue<IProgramRequest> _toCompile;
|
|
private readonly List<ThreadedProgram> _inProgress;
|
|
|
|
public ProgramQueue(IRenderer renderer)
|
|
{
|
|
_renderer = renderer;
|
|
|
|
_toCompile = new Queue<IProgramRequest>();
|
|
_inProgress = new List<ThreadedProgram>();
|
|
}
|
|
|
|
public void Add(IProgramRequest request)
|
|
{
|
|
lock (_toCompile)
|
|
{
|
|
_toCompile.Enqueue(request);
|
|
}
|
|
}
|
|
|
|
public void ProcessQueue()
|
|
{
|
|
for (int i = 0; i < _inProgress.Count; i++)
|
|
{
|
|
ThreadedProgram program = _inProgress[i];
|
|
|
|
ProgramLinkStatus status = program.Base.CheckProgramLink(false);
|
|
|
|
if (status != ProgramLinkStatus.Incomplete)
|
|
{
|
|
program.Compiled = true;
|
|
_inProgress.RemoveAt(i--);
|
|
}
|
|
}
|
|
|
|
int freeSpace = MaxConcurrentCompilations - _inProgress.Count;
|
|
|
|
for (int i = 0; i < freeSpace; i++)
|
|
{
|
|
// Begin compilation of some programs in the compile queue.
|
|
IProgramRequest program;
|
|
|
|
lock (_toCompile)
|
|
{
|
|
if (!_toCompile.TryDequeue(out program))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (program.Threaded.Base != null)
|
|
{
|
|
ProgramLinkStatus status = program.Threaded.Base.CheckProgramLink(false);
|
|
|
|
if (status != ProgramLinkStatus.Incomplete)
|
|
{
|
|
// This program is already compiled. Keep going through the queue.
|
|
program.Threaded.Compiled = true;
|
|
i--;
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
program.Threaded.Base = program.Create(_renderer);
|
|
}
|
|
|
|
_inProgress.Add(program.Threaded);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process the queue until the given program has finished compiling.
|
|
/// This will begin compilation of other programs on the queue as well.
|
|
/// </summary>
|
|
/// <param name="program">The program to wait for</param>
|
|
public void WaitForProgram(ThreadedProgram program)
|
|
{
|
|
Span<SpinWait> spinWait = stackalloc SpinWait[1];
|
|
|
|
while (!program.Compiled)
|
|
{
|
|
ProcessQueue();
|
|
|
|
if (!program.Compiled)
|
|
{
|
|
spinWait[0].SpinOnce(-1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|