github.com/moontrade/nogc@v0.1.7/alloc/tlsf/arena_sys.go (about)

     1  //go:build !tinygo
     2  // +build !tinygo
     3  
     4  package tlsf
     5  
     6  import (
     7  	"sync"
     8  	"unsafe"
     9  )
    10  
    11  type span struct {
    12  	p uintptr
    13  	n uintptr
    14  }
    15  
    16  type sysArena struct {
    17  	allocs map[uintptr]span
    18  	stat   sysMemStat
    19  	mu     sync.Mutex
    20  }
    21  
    22  func NewSysArena() *sysArena {
    23  	allocatorsMu.Lock()
    24  	a := &sysArena{}
    25  	if allocators == nil {
    26  		allocators = make(map[unsafe.Pointer]Arena)
    27  	}
    28  	allocators[unsafe.Pointer(a)] = a
    29  	allocatorsMu.Unlock()
    30  	return a
    31  }
    32  
    33  func (s *sysArena) Size() uint64 {
    34  	return uint64(s.stat)
    35  }
    36  
    37  func (a *sysArena) Alloc(size uintptr) (uintptr, uintptr) {
    38  	a.mu.Lock()
    39  	defer a.mu.Unlock()
    40  	ptr := sysAlloc(size, &a.stat)
    41  	if ptr == nil {
    42  		return 0, 0
    43  	}
    44  	if a.allocs == nil {
    45  		a.allocs = make(map[uintptr]span, 16)
    46  	}
    47  	a.allocs[uintptr(ptr)] = span{uintptr(ptr), size}
    48  	return uintptr(ptr), uintptr(ptr) + size
    49  }
    50  
    51  func (a *sysArena) Free() {
    52  	a.mu.Lock()
    53  	defer a.mu.Unlock()
    54  
    55  	if len(a.allocs) == 0 {
    56  		return
    57  	}
    58  
    59  	// Free all sysAllocs by calling sysFree
    60  	for k, v := range a.allocs {
    61  		sysFree(unsafe.Pointer(v.p), v.n, &a.stat)
    62  		delete(a.allocs, k)
    63  	}
    64  
    65  	allocatorsMu.Lock()
    66  	delete(allocators, unsafe.Pointer(a))
    67  	allocatorsMu.Unlock()
    68  }
    69  
    70  ////go:linkname sysMemStat runtime.sysMemStat
    71  type sysMemStat uint64
    72  
    73  ////go:linkname persistentalloc runtime.persistentalloc
    74  //func persistentalloc(size, align uintptr, sysStat *sysMemStat) unsafe.Pointer
    75  
    76  //go:linkname sysAlloc runtime.sysAlloc
    77  func sysAlloc(size uintptr, sysStat *sysMemStat) unsafe.Pointer
    78  
    79  //go:linkname sysFree runtime.sysFree
    80  func sysFree(ptr unsafe.Pointer, n uintptr, sysStat *sysMemStat)