Matt Jeanneret | cab955f | 2019-04-10 15:45:57 -0400 | [diff] [blame] | 1 | package bitmap |
| 2 | |
| 3 | import ( |
| 4 | "sync/atomic" |
| 5 | "unsafe" |
| 6 | ) |
| 7 | |
| 8 | // SetAtomicUint32 sets the target bit to the target value inside the uint32 |
| 9 | // encded bitmap. |
| 10 | func SetAtomicUint32(bitmap []uint32, targetBit int, targetValue bool) { |
| 11 | targetIndex := targetBit / 32 |
| 12 | BitOffset := targetBit % 32 |
| 13 | |
| 14 | for { |
| 15 | localValue := atomic.LoadUint32(&bitmap[targetIndex]) |
| 16 | targetBytes := (*[4]byte)(unsafe.Pointer(&localValue))[:] |
| 17 | if Get(targetBytes, BitOffset) == targetValue { |
| 18 | return |
| 19 | } |
| 20 | referenceValue := localValue |
| 21 | Set(targetBytes, BitOffset, targetValue) |
| 22 | if atomic.CompareAndSwapUint32(&bitmap[targetIndex], referenceValue, localValue) { |
| 23 | break |
| 24 | } |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | // GetAtomicUint32 gets the target bit from an uint32 encoded bitmap. |
| 29 | func GetAtomicUint32(bitmap []uint32, targetBit int) bool { |
| 30 | data := (*[4]byte)(unsafe.Pointer(&bitmap[targetBit/32]))[:] |
| 31 | return Get(data, targetBit%32) |
| 32 | } |