// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Lock-free stack.

package runtime

import (
	
	
)

// lfstack is the head of a lock-free stack.
//
// The zero value of lfstack is an empty list.
//
// This stack is intrusive. Nodes must embed lfnode as the first field.
//
// The stack does not keep GC-visible pointers to nodes, so the caller
// must ensure the nodes are allocated outside the Go heap.
type lfstack uint64

func ( *lfstack) ( *lfnode) {
	.pushcnt++
	 := lfstackPack(, .pushcnt)
	for {
		 := atomic.Load64((*uint64)())
		.next = 
		if atomic.Cas64((*uint64)(), , ) {
			break
		}
	}
}

func ( *lfstack) () unsafe.Pointer {
	for {
		 := atomic.Load64((*uint64)())
		if  == 0 {
			return nil
		}
		 := lfstackUnpack()
		 := atomic.Load64(&.next)
		if atomic.Cas64((*uint64)(), , ) {
			return unsafe.Pointer()
		}
	}
}

func ( *lfstack) () bool {
	return atomic.Load64((*uint64)()) == 0
}

// lfnodeValidate panics if node is not a valid address for use with
// lfstack.push. This only needs to be called when node is allocated.
func lfnodeValidate( *lfnode) {
	if , ,  := findObject(uintptr(unsafe.Pointer()), 0, 0);  != 0 {
		throw("lfstack node allocated from the heap")
	}
	lfstackPack(, ^uintptr(0))
}

func lfstackPack( *lfnode,  uintptr) uint64 {
	return uint64(taggedPointerPack(unsafe.Pointer(), &(1<<tagBits-1)))
}

func lfstackUnpack( uint64) *lfnode {
	return (*lfnode)(taggedPointer().pointer())
}