Help!
I installed zig 0.14.
Using vscode “something” must still hang in 0.13.
I even copied my project removing all cache stuff.
Could the Zig Language be out of date?
The thing I am stuck now is:
error: root source file struct ‘builtin’ has no member named ‘mode’
looking in the source I see that const there…
Ouch…
const builtin = @import(“builtin”);
What about the SmpAllocator.
I saw this (for me completely unreadable) example down here.
How do I initialize my smp allocator in one line 
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
pub fn main() !void {
const gpa, const is_debug = gpa: {
if (native_os == .wasi) break :gpa .{ std.heap.wasm_allocator, false };
break :gpa switch (builtin.mode) {
.Debug, .ReleaseSafe => .{ debug_allocator.allocator(), true },
.ReleaseFast, .ReleaseSmall => .{ std.heap.smp_allocator, false },
};
};
defer if (is_debug) {
_ = debug_allocator.deinit();
};
}
smp allocator uses threadlocal variables (which are shared across instances) so there can only be one instance at a time. There is a global instance provided by std: std.heap.smp_allocator
. You can just use that (similiar to page_allocator
).
The above example basically just gives you this global instance if you’re compiling in an unsafe release mode (or wasm_allocator
if you target the web) and a DebugAllocator
in safe modes. Since the debug allocator has to be instantiated and deinitialized by the user (in contrast to wasm_allocator and smp_allocator) the example uses a global debug_allocator
instance and a conditional defer
to deal with that.
I would recommend using zvm to manage your zig installations that way you can make sure that there’s only ever one zig/zls version in your path and remove any ambiguities that might cause trouble down the line.
i cant read that code (all untyped vars) and i really dont’t know how to use allocator or initialize it.
// A global debug allocator instance provided by the user since there can be multiple debug allocators at once
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
pub fn main() !void {
const gpa: std.mem.Allocator, const is_debug: bool = gpa: {
// use wasm_allocator for the web, there's an instance provided by std
if (native_os == .wasi) break :gpa .{ std.heap.wasm_allocator, false };
// switch on compiler optimize mode
break :gpa switch (builtin.mode) {
// safe mode: use our instance of debug_allocator, set the is_debug flag
.Debug, .ReleaseSafe => .{ debug_allocator.allocator(), true },
// 'unsafe' mode: use smp_allocator (because it's faster), instance is provided by std
.ReleaseFast, .ReleaseSmall => .{ std.heap.smp_allocator, false },
};
};
// we need to deinit our instance of debug_allocator (we could also check for leaks here). This only needs to happen if is_debug is set.
defer if (is_debug) {
_ = debug_allocator.deinit();
};
// if you simply want to use smp_allocator:
const gpa2: std.mem.Allocator = std.heap.smp_allocator;
// do something with it
const memory = try gpa2.alloc(u8, 1024);
defer gpa2.free(memory);
}
I hope this makes it clearer what’s happening here 
1 Like
Thanks! I still don’t get it but at least I can dive into it now.
As far as I can see I don’t need to deinit() the smp allocator. Just use it.
BTW: its not faster than the DebugAllocator
Yeah exactly, smp_allocator relies on you doing all the cleanup/freeing all allocations so there’s no deinit function.
I guess it depends on the workload whether smp_allocator is faster than DebugAllocator, if you’re not doing a lot of allocations anyways the difference is probably going to be negligible. But in multi-threaded environments and with a high-ish allocation count I guarantee you that smp_allocator will be faster it since that’s the entire reason for its existence in the first place
(read more about it here)
Given the intention that code use the DebugAllocator in debug modes and the SMP in other modes, it seems to me not excessive for the latter to have a no-op .deinit()
function, in the interest of streamlining the interface.
The alternative is rather a lot of code which has nothing to do with the problem domain, and compilation will completely remove the spurious function call.
3 Likes