xx/arena/arena.go

87 lines
2.1 KiB
Go

package arena
import (
"unsafe"
"git.brut.systems/judah/xx/mem"
)
// New returns a pointer to an Arena allocated value of type T.
// If allocation fails, New will panic.
//
// Note: Accessing the returned value after calling Reset is unsafe and may result in a fault.
func New[T any](arena Arena) *T {
ptr, err := arena(ACTION_ALLOC, mem.Sizeof[T](), mem.Alignof[T](), nil)
if err != nil {
panic(err)
}
return (*T)(ptr)
}
// MakeSlice creates an Arena allocated []T with the given capacity and length.
// If allocation fails, MakeSlice will panic.
//
// Note: Accessing the returned slice after calling Reset is unsafe and may result in a fault.
func MakeSlice[T any](arena Arena, len, cap int) []T {
ptr, err := arena(ACTION_ALLOC, mem.Sizeof[T]()*uintptr(len), mem.Alignof[T](), nil)
if err != nil {
panic(err)
}
return unsafe.Slice((*T)(ptr), cap)[:len]
}
// Reset restores an Arena to its initial state.
//
// Note: Accessing memory returned by an Arena after calling Reset is unsafe and may result in a fault.
func Reset(arena Arena) {
if _, err := arena(ACTION_RESET, 0, 0, nil); err != nil {
panic(err)
}
}
// Save returns the restorable state of an Arena.
// The returned value is internal to the particular Arena and should not be modified.
func Save(arena Arena) (watermark uintptr) {
if _, err := arena(ACTION_SAVE, 0, 0, &watermark); err != nil {
panic(err)
}
return
}
// Restore restores an Arena to a previously saved state.
func Restore(arena Arena, watermark uintptr) {
if _, err := arena(ACTION_RESTORE, 0, 0, &watermark); err != nil {
panic(err)
}
}
// Arena represents a memory allocator.
type Arena func(a Action, size, align uintptr, watermark *uintptr) (unsafe.Pointer, error)
// Action is a list of distinct events an Arena may respond to.
type Action int
const (
ACTION_ALLOC Action = iota
ACTION_RESET
ACTION_SAVE
ACTION_RESTORE
)
func (a Action) String() string {
switch a {
case ACTION_ALLOC:
return "ALLOC"
case ACTION_RESET:
return "RESET"
case ACTION_SAVE:
return "SAVE"
case ACTION_RESTORE:
return "RESTORE"
default:
panic("unreachable")
}
}