]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/lfstack.go
[dev.cc] all: merge default (95f5614b4648) into dev.cc
[gostls13.git] / src / runtime / lfstack.go
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                 gothrow("lfstackpush")
18         }
19         for {
20                 old := atomicload64(head)
21                 node.next, _ = lfstackUnpack(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                 node2 := (*lfnode)(atomicloadp(unsafe.Pointer(&node.next)))
36                 new := uint64(0)
37                 if node2 != nil {
38                         new = lfstackPack(node2, node2.pushcnt)
39                 }
40                 if cas64(head, old, new) {
41                         return unsafe.Pointer(node)
42                 }
43         }
44 }