66/// - Async background expansion when capacity threshold reached
77/// - Batched rendering support (groups draw calls by buffer)
88const std = @import ("std" );
9+ const Io = std .Io ;
910const volk = @import ("volk" );
1011const vk = volk .c ;
1112const shared = @import ("Shared" );
@@ -66,9 +67,12 @@ pub const GrowableBufferArena = struct {
6667 /// Async expansion state
6768 expansion_thread : ? std.Thread = null ,
6869 pending_arena : ? BufferArena = null ,
69- expansion_mutex : std.Thread. Mutex = .{} ,
70+ expansion_mutex : Io. Mutex = Io . Mutex . init ,
7071 expansion_failed : bool = false ,
7172
73+ /// I/O subsystem (needed for mutex operations)
74+ io : Io ,
75+
7276 /// Vulkan handles needed for creating new arenas
7377 device : vk.VkDevice ,
7478 physical_device : vk.VkPhysicalDevice ,
@@ -90,13 +94,15 @@ pub const GrowableBufferArena = struct {
9094 device : vk.VkDevice ,
9195 physical_device : vk.VkPhysicalDevice ,
9296 config : GrowableBufferConfig ,
97+ io : Io ,
9398 ) ! Self {
9499 var self = Self {
95100 .arenas = .{},
96101 .device = device ,
97102 .physical_device = physical_device ,
98103 .config = config ,
99104 .allocator = allocator ,
105+ .io = io ,
100106 };
101107
102108 // Pre-allocate initial arenas
@@ -137,6 +143,7 @@ pub const GrowableBufferArena = struct {
137143 usage : vk.VkBufferUsageFlags ,
138144 alignment : u64 ,
139145 avg_chunk_size : u64 ,
146+ io : Io ,
140147 ) ! Self {
141148 // Calculate expected chunk count
142149 const h_chunks = @as (u64 , view_distance ) * 2 + 1 ;
@@ -171,7 +178,7 @@ pub const GrowableBufferArena = struct {
171178 .initial_arena_count = @intCast (initial_arenas ),
172179 .usage = usage ,
173180 .alignment = alignment ,
174- });
181+ }, io );
175182 }
176183
177184 pub fn deinit (self : * Self ) void {
@@ -335,23 +342,23 @@ pub const GrowableBufferArena = struct {
335342 self .config .alignment ,
336343 ) catch | err | {
337344 logger .err ("Async arena allocation failed: {}" , .{err });
338- self .expansion_mutex .lock ( );
345+ self .expansion_mutex .lockUncancelable ( self . io );
339346 self .expansion_failed = true ;
340- self .expansion_mutex .unlock ();
347+ self .expansion_mutex .unlock (self . io );
341348 return ;
342349 };
343350
344- self .expansion_mutex .lock ( );
351+ self .expansion_mutex .lockUncancelable ( self . io );
345352 self .pending_arena = new_arena ;
346- self .expansion_mutex .unlock ();
353+ self .expansion_mutex .unlock (self . io );
347354
348355 logger .info ("Async arena allocation complete" , .{});
349356 }
350357
351358 /// Collect a pending arena if ready
352359 fn collectPendingArena (self : * Self ) void {
353- self .expansion_mutex .lock ( );
354- defer self .expansion_mutex .unlock ();
360+ self .expansion_mutex .lockUncancelable ( self . io );
361+ defer self .expansion_mutex .unlock (self . io );
355362
356363 if (self .pending_arena ) | arena | {
357364 self .arenas .append (self .allocator , arena ) catch | err | {
0 commit comments