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.
10 #if __SIZEOF_POINTER__ == 8
11 // Amd64 uses 48-bit virtual addresses, 47-th bit is used as kernel/user flag.
12 // So we use 17msb of pointers as ABA counter.
17 #define PTR_MASK ((1ull<<PTR_BITS)-1)
20 runtime_lfstackpush(uint64
*head
, LFNode
*node
)
24 if((uintptr
)node
!= ((uintptr
)node
&PTR_MASK
)) {
25 runtime_printf("p=%p\n", node
);
26 runtime_throw("runtime_lfstackpush: invalid pointer");
30 new = (uint64
)(uintptr
)node
|(((uint64
)node
->pushcnt
)<<PTR_BITS
);
31 old
= runtime_atomicload64(head
);
33 node
->next
= (LFNode
*)(uintptr
)(old
&PTR_MASK
);
34 if(runtime_cas64(head
, &old
, new))
40 runtime_lfstackpop(uint64
*head
)
45 old
= runtime_atomicload64(head
);
49 node
= (LFNode
*)(uintptr
)(old
&PTR_MASK
);
50 node2
= runtime_atomicloadp(&node
->next
);
53 new = (uint64
)(uintptr
)node2
|(((uint64
)node2
->pushcnt
)<<PTR_BITS
);
54 if(runtime_cas64(head
, &old
, new))
59 LFNode
* runtime_lfstackpop2(uint64
*)
60 asm("runtime.lfstackpop2");
63 runtime_lfstackpop2(uint64
*head
)
65 return runtime_lfstackpop(head
);