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

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