Skip to content

Commit

Permalink
Fix compressed frames
Browse files Browse the repository at this point in the history
  • Loading branch information
xoofx committed Dec 16, 2024
1 parent 0292c24 commit 0dbd59a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 13 deletions.
16 changes: 8 additions & 8 deletions src/Ultra.Sampler/MacOS/MacOSUltraSampler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal unsafe class MacOSUltraSampler : UltraSampler
private Thread? _samplerThread;
private ulong _samplerThreadId;
private readonly AutoResetEvent _samplerResumeThreadEvent;

// Frames information
private const int MaximumFrames = 4096;
private readonly ulong[] _frames; // 32 KB
Expand Down Expand Up @@ -366,7 +366,6 @@ private unsafe void Sample(MacOS.MacOSLibSystem.mach_port_t rootTask, NativeSamp
// Compute the same frame count
var sameFrameCount = ComputeSameFrameCount(threadInfo.thread_id, frameCount, pFrames);
frameCount -= sameFrameCount;
pFrames += sameFrameCount;

// Long only the delta frames
samplingDelegate(threadInfo.thread_id, (int)threadExtendedInfo.pth_run_state, (int)threadExtendedInfo.pth_cpu_usage, sameFrameCount, frameCount * sizeof(ulong), (byte*)pFrames);
Expand All @@ -387,9 +386,10 @@ private unsafe void Sample(MacOS.MacOSLibSystem.mach_port_t rootTask, NativeSamp
// Swap the active and current thread ids
(_currentThreadIds, _activeThreadIds) = (_activeThreadIds, _currentThreadIds);
}

private int ComputeSameFrameCount(ulong threadId, int frameCount, ulong* frames)
{
int originalFrameCount = frameCount;
// We limit the frame recording to MaximumCompressedFrameCount
frameCount = Math.Min(frameCount, MaximumCompressedFrameCount);

Expand Down Expand Up @@ -421,10 +421,10 @@ private int ComputeSameFrameCount(ulong threadId, int frameCount, ulong* frames)
int previousFrameCount = (int)previousFrame;
previousFrame = ref Unsafe.Add(ref previousFrame, 1);

var minFrameCount = Math.Min(previousFrameCount, frameCount);
for (; sameFrameCount < minFrameCount; sameFrameCount++)
var maxFrameCount = Math.Min(previousFrameCount, frameCount);
for (; sameFrameCount < maxFrameCount; sameFrameCount++)
{
if (frames[sameFrameCount] != previousFrame)
if (frames[originalFrameCount - sameFrameCount - 1] != previousFrame)
{
break;
}
Expand All @@ -439,9 +439,9 @@ private int ComputeSameFrameCount(ulong threadId, int frameCount, ulong* frames)
previousFrame = ref Unsafe.Add(ref previousFrame, 1);
for (int i = 0; i < frameCount; i++)
{
Unsafe.Add(ref previousFrame, i) = frames[i];
Unsafe.Add(ref previousFrame, i) = frames[originalFrameCount - i - 1];
}

return sameFrameCount;
}

Expand Down
16 changes: 11 additions & 5 deletions src/Ultra.Sampler/UltraSamplerSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,20 @@ private UltraSamplerSource()
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
public unsafe void NativeCallstack(ulong threadId, int threadState, int threadCpuUsage, int previousFrameCount, int framesSize, byte* frames) // frames is last to allow perfview to visualize previous fixed size arguments and also, it is an ulong otherwise the EventSource will silently fail to register!
{
var evt = stackalloc EventData[3];
var evt = stackalloc EventData[6];
evt[0].DataPointer = (nint)(void*)&threadId;
evt[0].Size = sizeof(ulong);
evt[1].DataPointer = (nint)(void*)&framesSize;
evt[1].DataPointer = (nint)(void*)&threadState;
evt[1].Size = sizeof(int);
evt[2].DataPointer = (nint)(void*)&frames;
evt[2].Size = framesSize;
WriteEventCore(UltraSamplerConstants.NativeCallStackEventId, 3, evt);
evt[2].DataPointer = (nint)(void*)&threadCpuUsage;
evt[2].Size = sizeof(int);
evt[3].DataPointer = (nint)(void*)&previousFrameCount;
evt[3].Size = sizeof(int);
evt[4].DataPointer = (nint)(void*)&framesSize;
evt[4].Size = sizeof(int);
evt[5].DataPointer = (nint)(void*)frames;
evt[5].Size = framesSize;
WriteEventCore(UltraSamplerConstants.NativeCallStackEventId, 6, evt);
}

[Event(UltraSamplerConstants.NativeModuleEventId, Level = EventLevel.Informational, Task = (EventTask)UltraSamplerConstants.TaskNativeModuleEventId)]
Expand Down

0 comments on commit 0dbd59a

Please sign in to comment.