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)