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

Tracy #2127

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open

Tracy #2127

Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project>
<Import Project="RobustToolbox/Directory.Packages.props" />
<ItemGroup>
<PackageVersion Include="NUnit.ConsoleRunner" Version="3.15.0" />
<PackageVersion Include="Byond.TopicSender" Version="8.0.1" />
</ItemGroup>
<Import Project="RobustToolbox/Directory.Packages.props" />
<ItemGroup>
<PackageVersion Include="NUnit.ConsoleRunner" Version="3.15.0" />
<PackageVersion Include="Byond.TopicSender" Version="8.0.1" />
<PackageVersion Include="Tracy-CSharp" Version="0.11.1-hotfix" />
</ItemGroup>
</Project>
41 changes: 28 additions & 13 deletions OpenDreamRuntime/DreamManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,17 @@ public void StartWorld() {
Initialized = true;
InitializedTick = _gameTiming.CurTick;

// Call global <init> with waitfor=FALSE
_objectTree.GlobalInitProc?.Spawn(WorldInstance, new());
using (Profiler.BeginZone("StartWorld", color:(uint)Color.OrangeRed.ToArgb())) {
// Call global <init> with waitfor=FALSE
_objectTree.GlobalInitProc?.Spawn(WorldInstance, new());

// Call New() on all /area and /turf that exist, each with waitfor=FALSE separately. If <global init> created any /area, call New a SECOND TIME
// new() up /objs and /mobs from compiled-in maps [order: (1,1) then (2,1) then (1,2) then (2,2)]
_dreamMapManager.InitializeAtoms(_compiledJson.Maps);
// Call New() on all /area and /turf that exist, each with waitfor=FALSE separately. If <global init> created any /area, call New a SECOND TIME
// new() up /objs and /mobs from compiled-in maps [order: (1,1) then (2,1) then (1,2) then (2,2)]
_dreamMapManager.InitializeAtoms(_compiledJson.Maps);

// Call world.New()
WorldInstance.SpawnProc("New");
// Call world.New()
WorldInstance.SpawnProc("New");
}
}

public void Shutdown() {
Expand All @@ -102,13 +104,26 @@ public void Shutdown() {
public void Update() {
if (!Initialized)
return;
using (Profiler.BeginZone("Tick", color:(uint)Color.OrangeRed.ToArgb()))
{
using (Profiler.BeginZone("DM Execution", color:(uint)Color.LightPink.ToArgb()))
_procScheduler.Process();

using (Profiler.BeginZone("Map Update", color:(uint)Color.LightPink.ToArgb())){
UpdateStat();
_dreamMapManager.UpdateTiles();
}

using (Profiler.BeginZone("Disk IO", color:(uint)Color.LightPink.ToArgb()))
Fixed Show fixed Hide fixed
DreamObjectSavefile.FlushAllUpdates();

WorldInstance.SetVariableValue("cpu", WorldInstance.GetVariable("tick_usage"));

using (Profiler.BeginZone("Deletion Queue", color:(uint)Color.LightPink.ToArgb()))
ProcessDelQueue();
}

_procScheduler.Process();
UpdateStat();
_dreamMapManager.UpdateTiles();
DreamObjectSavefile.FlushAllUpdates();
WorldInstance.SetVariableValue("cpu", WorldInstance.GetVariable("tick_usage"));
ProcessDelQueue();
Profiler.EmitFrameMark();
Fixed Show fixed Hide fixed
}

public void ProcessDelQueue() {
Expand Down
39 changes: 37 additions & 2 deletions OpenDreamRuntime/DreamThread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@
public abstract class ProcState : IDisposable {
private static int _idCounter = 0;
public int Id { get; } = ++_idCounter;

public abstract (string SourceFile, int Line) TracyLocationId { get; }
public ProfilerZone? TracyZoneId { get; set; }
public DreamThread Thread { get; set; }

[Access(typeof(ProcScheduler))]
Expand Down Expand Up @@ -210,7 +211,8 @@
var context = new DreamThread(proc.ToString());

if (proc is NativeProc nativeProc) {
return nativeProc.Call(context, src, usr, new(arguments));
using(Profiler.BeginZone(filePath:"Native Proc", lineNumber:0, memberName:nativeProc.Name))
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
return nativeProc.Call(context, src, usr, new(arguments));
}

var state = proc.CreateState(context, src, usr, new DreamProcArguments(arguments));
Expand Down Expand Up @@ -252,6 +254,13 @@
while (_current != null) {
ProcStatus status;
try {
if (Profiler.IsActivated() && _current.TracyZoneId is null && _current.Proc != null) { //IsActivated() call just for optimisation reasons
var location =_current.TracyLocationId;
var procpath = (_current.Proc.OwningType.Path.Equals("/") ? "/proc/" : _current.Proc.OwningType.Path+"/") +_current.Proc.Name;
// ReSharper disable ExplicitCallerInfoArgument
_current.TracyZoneId = Profiler.BeginZone(filePath: location.SourceFile, lineNumber: location.Line, memberName: procpath);
// ReSharper restore ExplicitCallerInfoArgument
}
// _current.Resume may mutate our state!!!
status = _current.Resume();
} catch (DMError dmError) {
Expand All @@ -274,8 +283,18 @@
switch (status) {
// The entire Thread is stopping
case ProcStatus.Cancelled:
if (_current.TracyZoneId is not null) {
_current.TracyZoneId.Value.Dispose();
_current.TracyZoneId = null;
}
var current = _current;
_current = null;
foreach (var s in _stack) {
if (s.TracyZoneId is null)
continue;
s.TracyZoneId.Value.Dispose();
s.TracyZoneId = null;
}
_stack.Clear();
resultStatus = status;
return current.Result;
Expand All @@ -298,6 +317,17 @@

// The context is done executing for now
case ProcStatus.Deferred:
if (_current.TracyZoneId is not null) {
_current.TracyZoneId.Value.Dispose();
_current.TracyZoneId = null;
}

foreach (var s in _stack) {
Fixed Show fixed Hide fixed
if (s.TracyZoneId is null)
continue;
s.TracyZoneId.Value.Dispose();
s.TracyZoneId = null;
}
// We return the current return value here even though it may not be the final result
resultStatus = status;
return _current.Result;
Expand Down Expand Up @@ -334,6 +364,11 @@
}

public void PopProcState(bool dispose = true) {
if (_current?.TracyZoneId is not null) {
_current.TracyZoneId.Value.Dispose();
_current.TracyZoneId = null;
}

if (_current?.WaitFor == false) {
_syncCount--;
}
Expand Down
3 changes: 3 additions & 0 deletions OpenDreamRuntime/EntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public override void Init() {
break;
}

if(_configManager.GetCVar(OpenDreamCVars.TracyEnable))
Fixed Show fixed Hide fixed
Profiler.ActivateTracy();

_prototypeManager.LoadDirectory(new ResPath("/Resources/Prototypes"));

_serverInfoManager.Initialize();
Expand Down
1 change: 1 addition & 0 deletions OpenDreamRuntime/OpenDreamRuntime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Byond.TopicSender" />
<PackageReference Include="Tracy-CSharp" />
</ItemGroup>

<Import Project="..\RobustToolbox\MSBuild\Robust.Properties.targets" />
Expand Down
2 changes: 2 additions & 0 deletions OpenDreamRuntime/Procs/AsyncNativeProc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public sealed class State : ProcState {
private AsyncNativeProc? _proc;
public override DreamProc? Proc => _proc;

public override (string SourceFile, int Line) TracyLocationId => ("Async Native Proc", 0);

private Func<State, Task<DreamValue>> _taskFunc;
private Task? _task;

Expand Down
10 changes: 9 additions & 1 deletion OpenDreamRuntime/Procs/DMProc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
}

public (string Source, int Line) GetSourceAtOffset(int offset) {
if(SourceInfo.Count == 0)
return ("<No Source Attached>",0);
SourceInfoJson current = SourceInfo[0];
string source = ObjectTree.Strings[current.File!.Value];

Expand Down Expand Up @@ -151,6 +153,8 @@

public override DreamProc? Proc => _proc;

public override (string SourceFile, int Line) TracyLocationId => ("<NO-OP>",0);

private DreamProc? _proc;

public override ProcStatus Resume() {
Expand Down Expand Up @@ -354,6 +358,9 @@
private DMProc _proc;
public override DMProc Proc => _proc;

public override (string SourceFile, int Line) TracyLocationId => _proc.GetSourceAtOffset(_pc+1);


/// Static initializer for maintainer friendly OpcodeHandlers to performance friendly _opcodeHandlers
static unsafe DMProcState() {
int maxOpcode = (int)_opcodeHandlers.Keys.Max();
Expand Down Expand Up @@ -481,7 +488,8 @@
public ProcStatus Call(DreamProc proc, DreamObject? src, DreamProcArguments arguments) {
if (proc is NativeProc p) {
// Skip a whole song and dance.
Push(p.Call(Thread, src, Usr, arguments));
using(Profiler.BeginZone(filePath:"Native Proc", lineNumber:0, memberName:p.Name))
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
Push(p.Call(Thread, src, Usr, arguments));
return ProcStatus.Continue;
}

Expand Down
4 changes: 3 additions & 1 deletion OpenDreamRuntime/Procs/InitDreamObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ internal sealed class InitDreamObjectState : ProcState {
private readonly DreamObjectTree _objectTree;

private enum Stage {
// Need to call the object's (init) proc
// Need to call the object's (init) proc
Init,

// Need to call IDreamMetaObject.OnObjectCreated & New
Expand Down Expand Up @@ -42,6 +42,8 @@ public void Initialize(DreamThread thread, DreamObject dreamObject, DreamObject?

public override DreamProc? Proc => null;

public override (string SourceFile, int Line) TracyLocationId => ($"new {_dreamObject.ObjectDefinition.Type}",0);

public override void AppendStackFrame(StringBuilder builder) {
builder.AppendLine($"new {_dreamObject.ObjectDefinition.Type}");
}
Expand Down
Loading
Loading