update to go 1.26; arena: fix Paged leaking its underlying memory
This commit is contained in:
parent
0671d04bb3
commit
04a5d3969d
2 changed files with 17 additions and 9 deletions
|
|
@ -187,17 +187,25 @@ func Paged(page_size, total_reserved_in_bytes uintptr) Arena {
|
||||||
offset uintptr
|
offset uintptr
|
||||||
)
|
)
|
||||||
|
|
||||||
base, err := mem.Reserve(total_reserved_in_bytes)
|
// @note(judah): Because, runtime.AddCleanup requires a Go-allocated
|
||||||
|
// pointer, we need to keep *something* around so we don't leak.
|
||||||
|
type cleanupwrapper struct {
|
||||||
|
data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := mem.Reserve(total_reserved_in_bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("paged: failed to reserve address space - %s", err))
|
panic(fmt.Sprintf("paged: failed to reserve address space - %s", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base := new(cleanupwrapper{data})
|
||||||
|
|
||||||
// @todo(judah): is this needed?
|
// @todo(judah): is this needed?
|
||||||
runtime.AddCleanup(&base, func(_ struct{}) {
|
runtime.AddCleanup(base, func(memory []byte) {
|
||||||
if err := mem.Release(base); err != nil {
|
if err := mem.Release(memory); err != nil {
|
||||||
panic(fmt.Sprintf("paged: failed to release memory - %s", err))
|
panic(fmt.Sprintf("paged: failed to release memory - %s", err))
|
||||||
}
|
}
|
||||||
}, struct{}{})
|
}, data)
|
||||||
|
|
||||||
return func(a Action, size, align uintptr, watermark *uintptr) (unsafe.Pointer, error) {
|
return func(a Action, size, align uintptr, watermark *uintptr) (unsafe.Pointer, error) {
|
||||||
switch a {
|
switch a {
|
||||||
|
|
@ -211,20 +219,20 @@ func Paged(page_size, total_reserved_in_bytes uintptr) Arena {
|
||||||
required := offset + aligned
|
required := offset + aligned
|
||||||
to_commit := mem.AlignForward(required, page_size)
|
to_commit := mem.AlignForward(required, page_size)
|
||||||
|
|
||||||
if err := mem.Commit(base[committed:to_commit], mem.AccessRead|mem.AccessWrite); err != nil {
|
if err := mem.Commit(base.data[committed:to_commit], mem.AccessRead|mem.AccessWrite); err != nil {
|
||||||
return nil, fmt.Errorf("paged: failed to commit memory - %w", err)
|
return nil, fmt.Errorf("paged: failed to commit memory - %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
committed = to_commit
|
committed = to_commit
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr := &base[offset]
|
ptr := &base.data[offset]
|
||||||
offset += aligned
|
offset += aligned
|
||||||
return unsafe.Pointer(ptr), nil
|
return unsafe.Pointer(ptr), nil
|
||||||
|
|
||||||
case ACTION_RESET:
|
case ACTION_RESET:
|
||||||
if committed > 0 {
|
if committed > 0 {
|
||||||
if err := mem.Decommit(base[:mem.AlignForward(committed, page_size)]); err != nil {
|
if err := mem.Decommit(base.data[:mem.AlignForward(committed, page_size)]); err != nil {
|
||||||
return nil, fmt.Errorf("paged: failed to decommit memory - %w", err)
|
return nil, fmt.Errorf("paged: failed to decommit memory - %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -248,7 +256,7 @@ func Paged(page_size, total_reserved_in_bytes uintptr) Arena {
|
||||||
return nil, errors.New("paged: cannot restore nil watermark")
|
return nil, errors.New("paged: cannot restore nil watermark")
|
||||||
}
|
}
|
||||||
|
|
||||||
clear(base[*watermark:offset])
|
clear(base.data[*watermark:offset])
|
||||||
offset = *watermark
|
offset = *watermark
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -1,5 +1,5 @@
|
||||||
module git.brut.systems/judah/xx
|
module git.brut.systems/judah/xx
|
||||||
|
|
||||||
go 1.25.0
|
go 1.26.0
|
||||||
|
|
||||||
require github.com/ebitengine/purego v0.9.1
|
require github.com/ebitengine/purego v0.9.1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue