Not quite… Each Arena_Temp holds what was the current block in the allocator when you called arena_temp_begin(), it will free all other blocks up until that one.
It’s easy to test this behaviour:
main :: proc() {
MIN_BLOCK :: virtual.DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE
a: virtual.Arena
if err := virtual.arena_init_growing(&a); err != nil do panic("EOM")
defer virtual.arena_destroy(&a)
_, _ = virtual.arena_alloc(&a, MIN_BLOCK, align_of(rawptr))
checkpoint0 := virtual.arena_temp_begin(&a)
fmt.printfln("1st block - reserved: %v, temp: %v", a.total_reserved, a.temp_count)
_, _ = virtual.arena_alloc(&a, MIN_BLOCK, align_of(rawptr))
checkpoint1 := virtual.arena_temp_begin(&a)
fmt.printfln("2nd block - reserved: %v, temp: %v", a.total_reserved, a.temp_count)
_, _ = virtual.arena_alloc(&a, MIN_BLOCK, align_of(rawptr))
checkpoint2 := virtual.arena_temp_begin(&a)
fmt.printfln("3rd block - reserved: %v, temp: %v", a.total_reserved, a.temp_count)
virtual.arena_temp_ignore(checkpoint2)
fmt.printfln("ignore cp2 - reserved: %v, temp: %v", a.total_reserved, a.temp_count)
virtual.arena_temp_ignore(checkpoint1)
fmt.printfln("ignore cp1 - reserved: %v, temp: %v", a.total_reserved, a.temp_count)
virtual.arena_temp_end(checkpoint0)
fmt.printfln("free until cp0 - reserved: %v, temp: %v", a.total_reserved, a.temp_count)
}
The above code will print:
1st block - reserved: 1048576, temp: 1
2nd block - reserved: 2097152, temp: 2
3rd block - reserved: 3145728, temp: 3
ignore cp2 - reserved: 3145728, temp: 2
ignore cp1 - reserved: 3145728, temp: 1
free until cp0 - reserved: 1048576, temp: 0
If you have persistent data in your arena, just do the allocation of those first, take a checkpoint and reset to that checkpoint at times when you are sure nothing else above that point is in use.
This approach assumes you have allocations going down the callstack and at the top level you can free. Basically, you can’t keep a block inbetween checkpoints.