@@ -193,3 +193,123 @@ pub inline fn isConnected() bool {
193193 }
194194 return false ;
195195}
196+
197+ // =============================================================================
198+ // Memory Profiling
199+ // =============================================================================
200+
201+ /// Report a memory allocation to Tracy
202+ pub inline fn alloc (ptr : ? * anyopaque , size : usize ) void {
203+ if (enabled ) {
204+ c .___tracy_emit_memory_alloc (ptr , size , 0 );
205+ }
206+ }
207+
208+ /// Report a memory allocation with name to Tracy
209+ pub inline fn allocNamed (ptr : ? * anyopaque , size : usize , comptime name : [:0 ]const u8 ) void {
210+ if (enabled ) {
211+ c .___tracy_emit_memory_alloc_named (ptr , size , 0 , name .ptr );
212+ }
213+ }
214+
215+ /// Report a memory free to Tracy
216+ pub inline fn free (ptr : ? * anyopaque ) void {
217+ if (enabled ) {
218+ c .___tracy_emit_memory_free (ptr , 0 );
219+ }
220+ }
221+
222+ /// Report a memory free with name to Tracy
223+ pub inline fn freeNamed (ptr : ? * anyopaque , comptime name : [:0 ]const u8 ) void {
224+ if (enabled ) {
225+ c .___tracy_emit_memory_free_named (ptr , 0 , name .ptr );
226+ }
227+ }
228+
229+ /// A wrapper allocator that reports all allocations to Tracy
230+ /// Use this to wrap your main allocator for memory profiling
231+ pub fn TracyAllocator (comptime name : ? [:0 ]const u8 ) type {
232+ return struct {
233+ parent_allocator : std.mem.Allocator ,
234+
235+ const Self = @This ();
236+
237+ pub fn init (parent : std.mem.Allocator ) Self {
238+ return .{ .parent_allocator = parent };
239+ }
240+
241+ pub fn allocator (self : * Self ) std.mem.Allocator {
242+ return .{
243+ .ptr = self ,
244+ .vtable = &.{
245+ .alloc = allocFn ,
246+ .resize = resizeFn ,
247+ .remap = remapFn ,
248+ .free = freeFn ,
249+ },
250+ };
251+ }
252+
253+ fn allocFn (ctx : * anyopaque , len : usize , alignment : std.mem.Alignment , ret_addr : usize ) ? [* ]u8 {
254+ const self : * Self = @ptrCast (@alignCast (ctx ));
255+ const result = self .parent_allocator .rawAlloc (len , alignment , ret_addr );
256+ if (enabled and result != null ) {
257+ if (name ) | n | {
258+ c .___tracy_emit_memory_alloc_named (result , len , 0 , n .ptr );
259+ } else {
260+ c .___tracy_emit_memory_alloc (result , len , 0 );
261+ }
262+ }
263+ return result ;
264+ }
265+
266+ fn resizeFn (ctx : * anyopaque , buf : []u8 , alignment : std.mem.Alignment , new_len : usize , ret_addr : usize ) bool {
267+ const self : * Self = @ptrCast (@alignCast (ctx ));
268+ if (self .parent_allocator .rawResize (buf , alignment , new_len , ret_addr )) {
269+ if (enabled ) {
270+ // Tracy doesn't have a resize, so report as free + alloc
271+ if (name ) | n | {
272+ c .___tracy_emit_memory_free_named (buf .ptr , 0 , n .ptr );
273+ c .___tracy_emit_memory_alloc_named (buf .ptr , new_len , 0 , n .ptr );
274+ } else {
275+ c .___tracy_emit_memory_free (buf .ptr , 0 );
276+ c .___tracy_emit_memory_alloc (buf .ptr , new_len , 0 );
277+ }
278+ }
279+ return true ;
280+ }
281+ return false ;
282+ }
283+
284+ fn remapFn (ctx : * anyopaque , memory : []u8 , alignment : std.mem.Alignment , new_len : usize , ret_addr : usize ) ? [* ]u8 {
285+ const self : * Self = @ptrCast (@alignCast (ctx ));
286+ const old_ptr = memory .ptr ;
287+ const result = self .parent_allocator .rawRemap (memory , alignment , new_len , ret_addr );
288+ if (enabled ) {
289+ if (result ) | new_ptr | {
290+ // Successful remap - report free of old, alloc of new
291+ if (name ) | n | {
292+ c .___tracy_emit_memory_free_named (old_ptr , 0 , n .ptr );
293+ c .___tracy_emit_memory_alloc_named (new_ptr , new_len , 0 , n .ptr );
294+ } else {
295+ c .___tracy_emit_memory_free (old_ptr , 0 );
296+ c .___tracy_emit_memory_alloc (new_ptr , new_len , 0 );
297+ }
298+ }
299+ }
300+ return result ;
301+ }
302+
303+ fn freeFn (ctx : * anyopaque , buf : []u8 , alignment : std.mem.Alignment , ret_addr : usize ) void {
304+ const self : * Self = @ptrCast (@alignCast (ctx ));
305+ if (enabled ) {
306+ if (name ) | n | {
307+ c .___tracy_emit_memory_free_named (buf .ptr , 0 , n .ptr );
308+ } else {
309+ c .___tracy_emit_memory_free (buf .ptr , 0 );
310+ }
311+ }
312+ self .parent_allocator .rawFree (buf , alignment , ret_addr );
313+ }
314+ };
315+ }
0 commit comments