Description
Background and motivation
Currently there is a very useful method to get the allocated bytes for the current thread: GC.GetAllocatedBytesForCurrentThread
. However, there is no way to get this for a given System.Threading.Thread object. This is useful for operations like iterating over threads and getting the allocations given what the thread is working on
The proposed method would be long System.Threading.Thread.GetAllocatedBytesForThread()
as an instance method added to the System.Threading.Thread class.
All of this information already exists and can be accessed using csharp from the gc_alloc_context associated with the Thread_data. We have implemented this on windows using:
var plngBytesAllocated = pData.m_alloc_context.alloc_bytes + pData.m_alloc_context.alloc_bytes_uoh - (pData.m_alloc_context.alloc_limit - pData.m_alloc_context.alloc_ptr);
static unsafe ref Thread_data GetCurrentNativeThread()
{
var currentNativeThread = GetNativeThread(Thread.CurrentThread);
return ref Unsafe.AsRef<Thread_data>((void*)currentNativeThread);
}
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_DONT_USE_InternalThread")]
static extern ref IntPtr GetNativeThread(Thread thread);
[StructLayout(LayoutKind.Sequential)]
unsafe struct Thread_data
{
public nint vtable;
public int m_state;
public int m_fPreemptiveGCDisabled;
public nint m_pFrame;
public nint m_pDomain;
public int m_ThreadId;
public nint m_pHead;
public LockEntry m_embeddedEntry;
public nint m_pBlockingLock;
public gc_alloc_context m_alloc_context;
public nint m_thAllocContextObj;
public nint m_pTEB;
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct gc_alloc_context
{
public nint alloc_ptr;
public nint alloc_limit;
public long alloc_bytes;
public long alloc_bytes_uoh;
public nint gc_reserved_1;
public nint gc_reserved_2;
public int alloc_count;
}
API Proposal
namespace System.Threading;
public class Thread
{
//....
public long GetAllocatedBytesForThread()
{
// implementation
}
}
var thread = System.Threading.Thread.CurrentThread;
Console.WriteLine($"Currently allocated bytes for thread: {thread.GetAllocatedBytesForThread()}");
API Usage
namespace System.Collections.Generic;
var thread = System.Threading.Thread.CurrentThread;
Console.WriteLine($"Currently allocated bytes for thread: {thread.GetAllocatedBytesForThread()}");
Alternative Designs
Potentially could be in GC via a static method that passes in the managed thread id: GC.GetAllocatedBytesForAThread(int threadID)
Risks
This is purely additive, so no breaking changes