1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
6 // Initialize head to 0, compare with 0 to test for emptiness.
7 // The stack does not keep pointers to nodes,
8 // so they can be garbage collected if there are no other pointers to nodes.
9 // The following code runs only in non-preemptible contexts.
14 "runtime/internal/atomic"
18 // Temporary for C code to call:
19 //go:linkname lfstackpush runtime.lfstackpush
20 //go:linkname lfstackpop runtime.lfstackpop
22 func lfstackpush(head
*uint64, node
*lfnode
) {
24 new := lfstackPack(node
, node
.pushcnt
)
25 if node1
:= lfstackUnpack(new); node1
!= node
{
26 print("runtime: lfstackpush invalid packing: node=", node
, " cnt=", hex(node
.pushcnt
), " packed=", hex(new), " -> node=", node1
, "\n")
30 old
:= atomic
.Load64(head
)
32 if atomic
.Cas64(head
, old
, new) {
38 func lfstackpop(head
*uint64) unsafe
.Pointer
{
40 old
:= atomic
.Load64(head
)
44 node
:= lfstackUnpack(old
)
45 next
:= atomic
.Load64(&node
.next
)
46 if atomic
.Cas64(head
, old
, next
) {
47 return unsafe
.Pointer(node
)