fix: Adds idle cpu config and forces on in debug (#790)
* Adds `core.enableIdleCPU` to modernuo.json * Forces idle CPU on in DEBUG * Reverts idle detection back to CPS
This commit is contained in:
parent
b6641c4853
commit
56c348ac68
7 changed files with 52 additions and 80 deletions
|
|
@ -55,7 +55,7 @@ namespace Server
|
||||||
evt.WaitOne();
|
evt.WaitOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ExecuteTasks()
|
public void ExecuteTasks()
|
||||||
{
|
{
|
||||||
if (Thread.CurrentThread != _mainThread)
|
if (Thread.CurrentThread != _mainThread)
|
||||||
{
|
{
|
||||||
|
|
@ -66,15 +66,11 @@ namespace Server
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (!_queue.TryDequeue(out var a))
|
if (_queue.TryDequeue(out var a))
|
||||||
{
|
{
|
||||||
return count;
|
a();
|
||||||
}
|
}
|
||||||
|
|
||||||
a();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3249,10 +3249,8 @@ namespace Server
|
||||||
m_DeltaFlags &= ~flags;
|
m_DeltaFlags &= ~flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ProcessDeltaQueue()
|
public static void ProcessDeltaQueue()
|
||||||
{
|
{
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
var limit = m_DeltaQueue.Count;
|
var limit = m_DeltaQueue.Count;
|
||||||
|
|
||||||
while (m_DeltaQueue.Count > 0 && --limit >= 0)
|
while (m_DeltaQueue.Count > 0 && --limit >= 0)
|
||||||
|
|
@ -3264,8 +3262,6 @@ namespace Server
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
|
||||||
|
|
||||||
item.SetFlag(ImplFlag.InQueue, false);
|
item.SetFlag(ImplFlag.InQueue, false);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -3286,8 +3282,6 @@ namespace Server
|
||||||
Console.WriteLine("Warning: {0} items left in delta queue after processing.", m_DeltaQueue.Count);
|
Console.WriteLine("Warning: {0} items left in delta queue after processing.", m_DeltaQueue.Count);
|
||||||
Utility.PopColor();
|
Utility.PopColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnDelete()
|
public virtual void OnDelete()
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,11 @@ namespace Server
|
||||||
set => _now = value;
|
set => _now = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long _cycleIndex = 1;
|
||||||
|
private static float[] _cyclesPerSecond = new float[100];
|
||||||
|
|
||||||
|
public static float CyclesPerSecond => _cyclesPerSecond[(_cycleIndex - 1) % _cyclesPerSecond.Length];
|
||||||
|
|
||||||
public static bool MultiProcessor { get; private set; }
|
public static bool MultiProcessor { get; private set; }
|
||||||
|
|
||||||
public static int ProcessorCount { get; private set; }
|
public static int ProcessorCount { get; private set; }
|
||||||
|
|
@ -488,40 +493,52 @@ namespace Server
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
var idleCPU = true;
|
||||||
|
#else
|
||||||
|
var idleCPU = ServerConfiguration.GetOrUpdateSetting("core.enableIdleCPU", false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
long last = TickCount;
|
||||||
const int interval = 100;
|
const int interval = 100;
|
||||||
int idleCount = 0;
|
const float ticksPerSecond = 1000 * interval;
|
||||||
|
|
||||||
|
int sample = 0;
|
||||||
|
|
||||||
while (!Closing)
|
while (!Closing)
|
||||||
{
|
{
|
||||||
_tickCount = TickCount;
|
_tickCount = TickCount;
|
||||||
_now = DateTime.UtcNow;
|
_now = DateTime.UtcNow;
|
||||||
|
|
||||||
var events = Mobile.ProcessDeltaQueue();
|
Mobile.ProcessDeltaQueue();
|
||||||
events += Item.ProcessDeltaQueue();
|
Item.ProcessDeltaQueue();
|
||||||
events += Timer.Slice(_tickCount);
|
Timer.Slice(_tickCount);
|
||||||
|
|
||||||
// Handle networking
|
// Handle networking
|
||||||
events += TcpServer.Slice();
|
TcpServer.Slice();
|
||||||
events += NetState.HandleAllReceives();
|
NetState.HandleAllReceives();
|
||||||
events += NetState.Slice();
|
NetState.Slice();
|
||||||
|
|
||||||
// Execute captured post-await methods (like Timer.Pause)
|
// Execute captured post-await methods (like Timer.Pause)
|
||||||
events += LoopContext.ExecuteTasks();
|
LoopContext.ExecuteTasks();
|
||||||
|
|
||||||
Timer.CheckTimerPool(); // Check for pool depletion so we can async refill it.
|
Timer.CheckTimerPool(); // Check for pool depletion so we can async refill it.
|
||||||
|
|
||||||
_tickCount = 0;
|
_tickCount = 0;
|
||||||
_now = DateTime.MinValue;
|
_now = DateTime.MinValue;
|
||||||
|
|
||||||
if (events > 0)
|
if (idleCPU && ++sample % interval == 0)
|
||||||
{
|
{
|
||||||
idleCount = 0;
|
var now = TickCount;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++idleCount > interval)
|
var cyclesPerSecond = ticksPerSecond / (now - last);
|
||||||
{
|
_cyclesPerSecond[_cycleIndex++ % _cyclesPerSecond.Length] = cyclesPerSecond;
|
||||||
Thread.Sleep(1);
|
last = now;
|
||||||
|
|
||||||
|
if (cyclesPerSecond > 80)
|
||||||
|
{
|
||||||
|
Thread.Sleep(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7848,10 +7848,8 @@ namespace Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ProcessDeltaQueue()
|
public static void ProcessDeltaQueue()
|
||||||
{
|
{
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
var limit = m_DeltaQueue.Count;
|
var limit = m_DeltaQueue.Count;
|
||||||
|
|
||||||
while (m_DeltaQueue.Count > 0 && --limit >= 0)
|
while (m_DeltaQueue.Count > 0 && --limit >= 0)
|
||||||
|
|
@ -7863,8 +7861,6 @@ namespace Server
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
|
||||||
|
|
||||||
mob.m_InDeltaQueue = false;
|
mob.m_InDeltaQueue = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -7885,8 +7881,6 @@ namespace Server
|
||||||
Console.WriteLine("Warning: {0} mobiles left in delta queue after processing.", m_DeltaQueue.Count);
|
Console.WriteLine("Warning: {0} mobiles left in delta queue after processing.", m_DeltaQueue.Count);
|
||||||
Utility.PopColor();
|
Utility.PopColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnKillsChange(int oldValue)
|
public virtual void OnKillsChange(int oldValue)
|
||||||
|
|
|
||||||
|
|
@ -538,16 +538,13 @@ namespace Server.Network
|
||||||
ThreadPool.UnsafeQueueUserWorkItem(SendTask, null);
|
ThreadPool.UnsafeQueueUserWorkItem(SendTask, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if there was any data to be processed. False otherwise. Used for idle detection.
|
public void HandleReceive()
|
||||||
public bool HandleReceive()
|
|
||||||
{
|
{
|
||||||
if (!Running)
|
if (!Running)
|
||||||
{
|
{
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool active = false;
|
|
||||||
|
|
||||||
var reader = RecvPipe.Reader;
|
var reader = RecvPipe.Reader;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -563,9 +560,6 @@ namespace Server.Network
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There was at least some data found, so it's not idle.
|
|
||||||
active = true;
|
|
||||||
|
|
||||||
var packetReader = new CircularBufferReader(result.Buffer);
|
var packetReader = new CircularBufferReader(result.Buffer);
|
||||||
var packetId = packetReader.ReadByte();
|
var packetId = packetReader.ReadByte();
|
||||||
int packetLength = length;
|
int packetLength = length;
|
||||||
|
|
@ -583,7 +577,7 @@ namespace Server.Network
|
||||||
case ProtocolState.Uninitialized:
|
case ProtocolState.Uninitialized:
|
||||||
{
|
{
|
||||||
HandleError(packetId, packetLength);
|
HandleError(packetId, packetLength);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ProtocolState.AwaitingSeed:
|
case ProtocolState.AwaitingSeed:
|
||||||
|
|
@ -604,7 +598,7 @@ namespace Server.Network
|
||||||
if (seed == 0)
|
if (seed == 0)
|
||||||
{
|
{
|
||||||
HandleError(0, 0);
|
HandleError(0, 0);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_seed = seed;
|
_seed = seed;
|
||||||
|
|
@ -626,7 +620,7 @@ namespace Server.Network
|
||||||
{
|
{
|
||||||
LogInfo("Possible encrypted client detected, disconnecting...");
|
LogInfo("Possible encrypted client detected, disconnecting...");
|
||||||
HandleError(packetId, packetLength);
|
HandleError(packetId, packetLength);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_parserState = ParserState.ProcessingPacket;
|
_parserState = ParserState.ProcessingPacket;
|
||||||
|
|
@ -643,7 +637,7 @@ namespace Server.Network
|
||||||
if (packetId != 0xA0)
|
if (packetId != 0xA0)
|
||||||
{
|
{
|
||||||
HandleError(packetId, packetLength);
|
HandleError(packetId, packetLength);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_parserState = ParserState.ProcessingPacket;
|
_parserState = ParserState.ProcessingPacket;
|
||||||
|
|
@ -665,7 +659,7 @@ namespace Server.Network
|
||||||
_parserState = ParserState.AwaitingNextPacket;
|
_parserState = ParserState.AwaitingNextPacket;
|
||||||
_protocolState = ProtocolState.AwaitingSeed;
|
_protocolState = ProtocolState.AwaitingSeed;
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ProtocolState.GameServer_AwaitingGameServerLogin:
|
case ProtocolState.GameServer_AwaitingGameServerLogin:
|
||||||
|
|
@ -673,7 +667,7 @@ namespace Server.Network
|
||||||
if (packetId != 0x91 && packetId != 0x80)
|
if (packetId != 0x91 && packetId != 0x80)
|
||||||
{
|
{
|
||||||
HandleError(packetId, packetLength);
|
HandleError(packetId, packetLength);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_parserState = ParserState.ProcessingPacket;
|
_parserState = ParserState.ProcessingPacket;
|
||||||
|
|
@ -719,8 +713,6 @@ namespace Server.Network
|
||||||
TraceException(ex);
|
TraceException(ex);
|
||||||
Disconnect("Exception during HandleReceive");
|
Disconnect("Exception during HandleReceive");
|
||||||
}
|
}
|
||||||
|
|
||||||
return active;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|
@ -962,19 +954,12 @@ namespace Server.Network
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int HandleAllReceives()
|
public static void HandleAllReceives()
|
||||||
{
|
{
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
foreach (var ns in TcpServer.Instances)
|
foreach (var ns in TcpServer.Instances)
|
||||||
{
|
{
|
||||||
if (ns.HandleReceive())
|
ns.HandleReceive();
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Flush()
|
public void Flush()
|
||||||
|
|
@ -995,13 +980,11 @@ namespace Server.Network
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int Slice()
|
public static void Slice()
|
||||||
{
|
{
|
||||||
int count = 0;
|
|
||||||
while (FlushPending.Count != 0)
|
while (FlushPending.Count != 0)
|
||||||
{
|
{
|
||||||
FlushPending.Dequeue()?.Flush();
|
FlushPending.Dequeue()?.Flush();
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (Disposed.TryDequeue(out var ns))
|
while (Disposed.TryDequeue(out var ns))
|
||||||
|
|
@ -1009,8 +992,6 @@ namespace Server.Network
|
||||||
TcpServer.Instances.Remove(ns);
|
TcpServer.Instances.Remove(ns);
|
||||||
ns.Dispose();
|
ns.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CheckAlive(long curTicks)
|
public void CheckAlive(long curTicks)
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ namespace Server.Network
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int Slice()
|
public static void Slice()
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
@ -132,8 +132,6 @@ namespace Server.Network
|
||||||
ns.LogInfo("Connected. [{0} Online]", Instances.Count);
|
ns.LogInfo("Connected. [{0} Online]", Instances.Count);
|
||||||
ns.Start();
|
ns.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async void BeginAcceptingSockets(this TcpListener listener)
|
private static async void BeginAcceptingSockets(this TcpListener listener)
|
||||||
|
|
|
||||||
|
|
@ -45,23 +45,19 @@ namespace Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int Slice(long tickCount)
|
public static void Slice(long tickCount)
|
||||||
{
|
{
|
||||||
var deltaSinceTurn = tickCount - _lastTickTurned;
|
var deltaSinceTurn = tickCount - _lastTickTurned;
|
||||||
var events = 0;
|
|
||||||
while (deltaSinceTurn >= _tickRate)
|
while (deltaSinceTurn >= _tickRate)
|
||||||
{
|
{
|
||||||
deltaSinceTurn -= _tickRate;
|
deltaSinceTurn -= _tickRate;
|
||||||
_lastTickTurned += _tickRate;
|
_lastTickTurned += _tickRate;
|
||||||
events += Turn() ? 1 : 0;
|
Turn();
|
||||||
}
|
}
|
||||||
|
|
||||||
return events;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool Turn()
|
private static void Turn()
|
||||||
{
|
{
|
||||||
bool events = false;
|
|
||||||
_timerWheelExecuting = true;
|
_timerWheelExecuting = true;
|
||||||
var turnNextWheel = false;
|
var turnNextWheel = false;
|
||||||
|
|
||||||
|
|
@ -97,8 +93,6 @@ namespace Server
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
events = true;
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var next = timer._nextTimer;
|
var next = timer._nextTimer;
|
||||||
|
|
@ -124,8 +118,6 @@ namespace Server
|
||||||
}
|
}
|
||||||
|
|
||||||
_timerWheelExecuting = false;
|
_timerWheelExecuting = false;
|
||||||
|
|
||||||
return events;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Execute(Timer timer)
|
private static void Execute(Timer timer)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue