github.com/fjballest/golang@v0.0.0-20151209143359-e4c5fe594ca8/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 ( 11 "runtime/internal/atomic" 12 "unsafe" 13 ) 14 15 func lfstackpush(head *uint64, node *lfnode) { 16 node.pushcnt++ 17 new := lfstackPack(node, node.pushcnt) 18 if node1, _ := lfstackUnpack(new); node1 != node { 19 print("runtime: lfstackpush invalid packing: node=", node, " cnt=", hex(node.pushcnt), " packed=", hex(new), " -> node=", node1, "\n") 20 throw("lfstackpush") 21 } 22 for { 23 old := atomic.Load64(head) 24 node.next = old 25 if atomic.Cas64(head, old, new) { 26 break 27 } 28 } 29 } 30 31 func lfstackpop(head *uint64) unsafe.Pointer { 32 for { 33 old := atomic.Load64(head) 34 if old == 0 { 35 return nil 36 } 37 node, _ := lfstackUnpack(old) 38 next := atomic.Load64(&node.next) 39 if atomic.Cas64(head, old, next) { 40 return unsafe.Pointer(node) 41 } 42 } 43 }