@@ -11,13 +11,12 @@ pub fn CircularBuffer(comptime T: type) type {
1111 read_offset : usize = 0 ,
1212 write_offset : usize = 0 ,
1313
14- /// `capacity` * sizeof(T) must be a multiple of page size.
14+ /// `capacity` * sizeof(T) must be a multiple of page size on Linux (most likely 4k) or allocation granularity on Windows (most likely 64k) .
1515 pub fn init (capacity : usize ) ! @This () {
1616 const byte_capacity = capacity * @sizeOf (T );
17- if (byte_capacity % std . heap . pageSize () != 0 ) return error .InvalidSize ;
17+ if (byte_capacity % allocation_granularity () != 0 ) return error .InvalidSize ;
1818 switch (builtin .os .tag ) {
1919 .windows = > {
20- // FIXME: UNTESTED!
2120 const fd = CreateFileMappingA (
2221 std .os .windows .INVALID_HANDLE_VALUE ,
2322 null ,
@@ -29,7 +28,7 @@ pub fn CircularBuffer(comptime T: type) type {
2928 defer _ = std .os .windows .CloseHandle (fd );
3029
3130 // FIXME: Use placeholders instead of the retry loop...
32- while ( true ) {
31+ for (0 .. 8) | _ | {
3332 const reserve = VirtualAlloc (null , 2 * byte_capacity , MEM_RESERVE , PAGE_NOACCESS ) orelse return error .VirtualAllocError ;
3433 _ = VirtualFree (reserve , 0 , MEM_RELEASE );
3534
@@ -44,6 +43,8 @@ pub fn CircularBuffer(comptime T: type) type {
4443 .buffer = @alignCast (std .mem .bytesAsSlice (T , @as ([* ]u8 , @ptrCast (reserve ))[0 .. 2 * byte_capacity ])),
4544 };
4645 }
46+ std .log .err ("Failed to allocate Circular Buffer: {}" , .{std .os .windows .GetLastError ()});
47+ return error .MapViewOfFileExError ;
4748 },
4849 .linux = > {
4950 const fd = try std .posix .memfd_create ("Circular Buffer" , 0 );
@@ -66,10 +67,10 @@ pub fn CircularBuffer(comptime T: type) type {
6667 }
6768
6869 /// Initializes the buffer with at least `capacity` elements.
69- /// Actual capacity may be greater to be a multiple of page size .
70+ /// Actual capacity may be greater to be a multiple of the required alignement .
7071 pub fn initAtLeast (capacity : usize ) ! @This () {
7172 const byte_capacity = capacity * @sizeOf (T );
72- return init (std .mem .alignForward (usize , byte_capacity , std . heap . pageSize ()) / @sizeOf (T ));
73+ return init (std .mem .alignForward (usize , byte_capacity , allocation_granularity ()) / @sizeOf (T ));
7374 }
7475
7576 pub fn deinit (self : * @This ()) void {
@@ -109,6 +110,18 @@ pub fn CircularBuffer(comptime T: type) type {
109110 pub fn view (self : * const @This ()) []const T {
110111 return self .buffer [self .read_offset .. self .write_offset ];
111112 }
113+
114+ fn allocation_granularity () usize {
115+ switch (builtin .os .tag ) {
116+ .windows = > {
117+ var system_info : SYSTEM_INFO = undefined ;
118+ GetSystemInfo (& system_info );
119+ return system_info .dwAllocationGranularity ;
120+ },
121+ .linux = > return std .heap .pageSize (),
122+ else = > @compileError ("Unsupported OS" ),
123+ }
124+ }
112125 };
113126}
114127
@@ -118,6 +131,29 @@ pub const MEM_RELEASE: std.os.windows.DWORD = 0x00008000;
118131pub const PAGE_NOACCESS : std.os.windows.DWORD = 0x01 ;
119132pub const PAGE_READWRITE : std.os.windows.DWORD = 0x04 ;
120133
134+ pub const SYSTEM_INFO = extern struct {
135+ id : extern union {
136+ dwOemId : std.os.windows.DWORD ,
137+ other : extern struct {
138+ wProcessorArchitecture : std.os.windows.WORD ,
139+ wReserved : std.os.windows.WORD ,
140+ },
141+ },
142+ dwPageSize : std.os.windows.DWORD ,
143+ lpMinimumApplicationAddress : std.os.windows.LPVOID ,
144+ lpMaximumApplicationAddress : std.os.windows.LPVOID ,
145+ dwActiveProcessorMask : std.os.windows.DWORD_PTR ,
146+ dwNumberOfProcessors : std.os.windows.DWORD ,
147+ dwProcessorType : std.os.windows.DWORD ,
148+ dwAllocationGranularity : std.os.windows.DWORD ,
149+ wProcessorLevel : std.os.windows.WORD ,
150+ wProcessorRevision : std.os.windows.WORD ,
151+ };
152+
153+ pub extern "kernel32" fn GetSystemInfo (
154+ lpSystemInfo : * SYSTEM_INFO ,
155+ ) callconv (.winapi ) void ;
156+
121157pub extern "kernel32" fn CreateFileMappingA (
122158 hFile : std.os.windows.HANDLE ,
123159 lpFileMappingAttributes : ? * std.os.windows.SECURITY_ATTRIBUTES ,
0 commit comments