github.com/pidato/unsafe@v0.1.4/memory/tlsf/arena_slice.go (about)

     1  //go:build !tinygo && !wasm && !wasi && !tinygo.wasm
     2  
     3  package tlsf
     4  
     5  import (
     6  	"sync"
     7  	"unsafe"
     8  )
     9  
    10  var (
    11  	allocators   map[unsafe.Pointer]Arena
    12  	allocatorsMu sync.Mutex
    13  )
    14  
    15  // SliceArena allocates memory by creating Go byte slices
    16  type SliceArena struct {
    17  	allocations map[uintptr][]byte
    18  }
    19  
    20  func NewSliceArena() *SliceArena {
    21  	// Allocate on Go GC
    22  	a := &SliceArena{
    23  		allocations: make(map[uintptr][]byte, 16),
    24  	}
    25  	allocatorsMu.Lock()
    26  	if allocators == nil {
    27  		allocators = make(map[unsafe.Pointer]Arena)
    28  	}
    29  	allocators[unsafe.Pointer(a)] = a
    30  	allocatorsMu.Unlock()
    31  	return a
    32  }
    33  
    34  func (a *SliceArena) Alloc(size uintptr) (uintptr, uintptr) {
    35  	b := make([]byte, size)
    36  	p := unsafe.Pointer(&b[0])
    37  	a.allocations[uintptr(p)] = b
    38  	return uintptr(p), uintptr(p) + uintptr(cap(b))
    39  }
    40  
    41  func (a *SliceArena) Free() {
    42  	allocatorsMu.Lock()
    43  	defer allocatorsMu.Unlock()
    44  	// Clear all allocs to help GC marking
    45  	for k := range a.allocations {
    46  		delete(a.allocations, k)
    47  	}
    48  	// Remove from global allocators map and the GC will free when needed
    49  	delete(allocators, unsafe.Pointer(a))
    50  }