package runtime
import (
"runtime/internal/atomic"
"unsafe"
)
type lfstack uint64
func (head *lfstack ) push (node *lfnode ) {
node .pushcnt ++
new := lfstackPack (node , node .pushcnt )
if node1 := lfstackUnpack (new ); node1 != node {
print ("runtime: lfstack.push invalid packing: node=" , node , " cnt=" , hex (node .pushcnt ), " packed=" , hex (new ), " -> node=" , node1 , "\n" )
throw ("lfstack.push" )
}
for {
old := atomic .Load64 ((*uint64 )(head ))
node .next = old
if atomic .Cas64 ((*uint64 )(head ), old , new ) {
break
}
}
}
func (head *lfstack ) pop () unsafe .Pointer {
for {
old := atomic .Load64 ((*uint64 )(head ))
if old == 0 {
return nil
}
node := lfstackUnpack (old )
next := atomic .Load64 (&node .next )
if atomic .Cas64 ((*uint64 )(head ), old , next ) {
return unsafe .Pointer (node )
}
}
}
func (head *lfstack ) empty () bool {
return atomic .Load64 ((*uint64 )(head )) == 0
}
func lfnodeValidate (node *lfnode ) {
if base , _ , _ := findObject (uintptr (unsafe .Pointer (node )), 0 , 0 ); base != 0 {
throw ("lfstack node allocated from the heap" )
}
if lfstackUnpack (lfstackPack (node , ^uintptr (0 ))) != node {
printlock ()
println ("runtime: bad lfnode address" , hex (uintptr (unsafe .Pointer (node ))))
throw ("bad lfnode address" )
}
}
func lfstackPack (node *lfnode , cnt uintptr ) uint64 {
return uint64 (taggedPointerPack (unsafe .Pointer (node ), cnt ))
}
func lfstackUnpack (val uint64 ) *lfnode {
return (*lfnode )(taggedPointer (val ).pointer ())
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .