0

I have a byte slice in golang that contains binary data. Now in that slice there is a 32 bit integer that acts as a lock. The slice comes from mapped memory so another process is accessing the same data. Now I need to be able to atomically CompareAndSwap the contents of the 32 bit value.

example:

// before:
// slice data                    [ ---  lock value  --- ]
// []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ...}
//
// do atomic compare and swap with []byte{0x00, 0x00, 0x00, 0x01} on a given 
// index in the original slice.
// after the operation the original slice should contain:
// new data                       [ ---  lock value  --- ] 
// []byte{0x00, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x00, 0x01 ...}

I looked at the atomic.CompareAndSwapPointer method in combination with unsafe.Pointer but I can't get it to work. Is the above behavior even possible in go? Note that I need the operation to be atomic across other processes. So not only within the current go process.

wipsel
  • 21
  • 2
  • 1
    You don't want to swap a pointer to your value, you need to swap the actual value in memory, so you would use `CompareAndSwapUint32` or `CompareAndSwapInt32` – JimB Jul 31 '23 at 18:24
  • 3
    Is your 32-bit integer aligned? In your example, you show modifying the last byte of 7. That's one of the middle bytes of an aligned 32-bit unit if the slice started at a 4-byte boundary. Normally for a spinlock you'd just be flipping the least-significant bit of a byte or word, so on a little-endian machine that would be the 1st or 5th byte of the slice if it's aligned and you want to do it with an aligned Uint32 instead of just a byte CAS. – Peter Cordes Jul 31 '23 at 18:24
  • The example only shows the usecase, I did not really put the actual data structure in. But @PeterCordes you are correct i only want to change one bit in a uint32. But I need to be able to do the operation directly in the original slice. – wipsel Jul 31 '23 at 18:51
  • 2
    I understand that. I'm pointing out that your example shows a situation complicated by potential misalignment of the uint32 you'd want to CAS. Hopefully that's not the case in your real code, so you should make your example simpler. (Also, does Go not have byte operand-size for CAS operations?) – Peter Cordes Jul 31 '23 at 19:26
  • Ah thanks for pointing that out. I will change the example. – wipsel Jul 31 '23 at 19:36
  • With the help of this https://stackoverflow.com/a/11926852/11873822 I was able to achieve what I needed. See https://go.dev/play/p/E12WpS_6uFK – wipsel Aug 01 '23 at 14:46

0 Answers0