rsc.io/go@v0.0.0-20150416155037-e040fd465409/src/runtime/lfstack.go (about)

     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.
     4  
     5  // Lock-free stack.
     6  // The following code runs only on g0 stack.
     7  
     8  package runtime
     9  
    10  import "unsafe"
    11  
    12  func lfstackpush(head *uint64, node *lfnode) {
    13  	node.pushcnt++
    14  	new := lfstackPack(node, node.pushcnt)
    15  	if node1, _ := lfstackUnpack(new); node1 != node {
    16  		println("runtime: lfstackpush invalid packing: node=", node, " cnt=", hex(node.pushcnt), " packed=", hex(new), " -> node=", node1, "\n")
    17  		throw("lfstackpush")
    18  	}
    19  	for {
    20  		old := atomicload64(head)
    21  		node.next = old
    22  		if cas64(head, old, new) {
    23  			break
    24  		}
    25  	}
    26  }
    27  
    28  func lfstackpop(head *uint64) unsafe.Pointer {
    29  	for {
    30  		old := atomicload64(head)
    31  		if old == 0 {
    32  			return nil
    33  		}
    34  		node, _ := lfstackUnpack(old)
    35  		next := atomicload64(&node.next)
    36  		if cas64(head, old, next) {
    37  			return unsafe.Pointer(node)
    38  		}
    39  	}
    40  }