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") } }