package lock import ( "github.com/petermattis/goid" "github.com/tursom/GoCollections/exceptions" "github.com/tursom/GoCollections/lang/atomic" ) type ( CLH struct { tail atomic.Reference[clhNode] state atomic.Reference[clhNode] } clhNode struct { prev *clhNode locked atomic.Bool gid int64 } ) func (c *CLH) Lock() { node := &clhNode{ prev: c.tail.Load(), locked: 1, // true gid: goid.Get(), } for !c.tail.CompareAndSwap(node.prev, node) { node.prev = c.tail.Load() } if node.prev == nil { return } for node.prev.locked.Load() { } c.state.Store(node) } func (c *CLH) Unlock() { node := c.state.Load() if node.gid != goid.Get() { panic(exceptions.NewIllegalAccessException("unlock with wrong goroutine", nil)) } node.locked.Store(false) }