78 lines
1.7 KiB
Go
78 lines
1.7 KiB
Go
package alloc
|
|
|
|
import (
|
|
"unsafe"
|
|
|
|
"git.brut.systems/judah/xx/mem"
|
|
)
|
|
|
|
// New returns a pointer to an Allocator allocated value of type T.
|
|
//
|
|
// Note: If allocation fails, New will panic.
|
|
func New[T any](alloc Allocator) *T {
|
|
ptr, err := alloc(ActionAlloc, mem.SizeOf[T](), mem.AlignOf[T](), nil)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return (*T)(ptr)
|
|
}
|
|
|
|
// Reset restores an Allocator to its initial state.
|
|
//
|
|
// Note: Use of memory allocated by an Allocator after calling Reset is unsafe.
|
|
func Reset(alloc Allocator) {
|
|
if _, err := alloc(ActionReset, 0, 0, nil); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// Save returns the current state of an Allocator.
|
|
//
|
|
// Note: The value returned is internal to the particular Allocator Save was called on.
|
|
// The value should not be modified.
|
|
func Save(alloc Allocator) (watermark uintptr) {
|
|
if _, err := alloc(ActionSave, 0, 0, &watermark); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// Restore restores an Allocator to a previously saved state.
|
|
func Restore(alloc Allocator, watermark uintptr) {
|
|
if _, err := alloc(ActionRestore, 0, 0, &watermark); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// Allocator represents a memory allocator.
|
|
type Allocator func(a Action, size, align uintptr, watermark *uintptr) (unsafe.Pointer, error)
|
|
|
|
// Action is a list of distinct events an Allocator may respond to.
|
|
type Action int
|
|
|
|
const (
|
|
ActionAlloc Action = iota
|
|
ActionReset
|
|
ActionSave
|
|
ActionRestore
|
|
ActionReport
|
|
)
|
|
|
|
func (a Action) String() string {
|
|
switch a {
|
|
case ActionAlloc:
|
|
return "Alloc"
|
|
case ActionReset:
|
|
return "Reset"
|
|
case ActionSave:
|
|
return "Save"
|
|
case ActionRestore:
|
|
return "Restore"
|
|
case ActionReport:
|
|
return "Report"
|
|
default:
|
|
panic("unreachable")
|
|
}
|
|
}
|