github.com/tursom/GoCollections@v0.3.10/concurrent/lock/CLH.go (about) 1 package lock 2 3 import ( 4 "github.com/petermattis/goid" 5 6 "github.com/tursom/GoCollections/exceptions" 7 "github.com/tursom/GoCollections/lang/atomic" 8 ) 9 10 type ( 11 CLH struct { 12 tail atomic.Reference[clhNode] 13 state atomic.Reference[clhNode] 14 } 15 16 clhNode struct { 17 prev *clhNode 18 locked atomic.Bool 19 gid int64 20 } 21 ) 22 23 func (c *CLH) Lock() { 24 node := &clhNode{ 25 prev: c.tail.Load(), 26 locked: 1, // true 27 gid: goid.Get(), 28 } 29 30 for !c.tail.CompareAndSwap(node.prev, node) { 31 node.prev = c.tail.Load() 32 } 33 34 if node.prev == nil { 35 return 36 } 37 38 for node.prev.locked.Load() { 39 } 40 41 c.state.Store(node) 42 } 43 44 func (c *CLH) Unlock() { 45 node := c.state.Load() 46 if node.gid != goid.Get() { 47 panic(exceptions.NewIllegalAccessException("unlock with wrong goroutine", nil)) 48 } 49 50 node.locked.Store(false) 51 }