On Fri, Apr 1, 2022 at 8:31 PM 机智的小小帅 <liweiforeveryo...@gmail.com> wrote:
>
> Hi,all. I'm reading the source code of sync package recently.
>
> Here is a code snippet in sync/mutex.go.
>
> // src/sync/mutex.go
> type Mutex struct {
>     state int32
>     sema  uint32
> }
>
> func (m *Mutex) lockSlow() {
>     var waitStartTime int64
>     starving := false
>     awoke := false
>     iter := 0
>     old := m.state // Here!!! not use atomic.LoadInt32()
>     for {
>         // Don't spin in starvation mode, ownership is handed off to waiters
>         // so we won't be able to acquire the mutex anyway.
>         if old&(mutexLocked|mutexStarving) == mutexLocked && 
> runtime_canSpin(iter) {
>             // Active spinning makes sense.
>             // Try to set mutexWoken flag to inform Unlock
>             // to not wake other blocked goroutines.
>             if !awoke && old&mutexWoken == 0 && old>>mutexWaiterShift != 0 &&
>                 atomic.CompareAndSwapInt32(&m.state, old, old|mutexWoken) {
>                 awoke = true
>             }
>             // ...
>             old = m.state // And here!!! not use atomic.LoadInt32()
>             continue
>         }
>     // ...
>   }
>   // ...
> }
>
>
> You can see full context in link1 and link2
>
> I have read The Go Memory Model, It says "Reads and writes of values larger 
> than a single machine word behave as multiple machine-word-sized operations 
> in an unspecified order."
>
> Althought it is usually 32 or 64 bits on modern machine,I think if you want a 
> operator is atomic,you should use atomic.LoadXXX() explicitly.
>
> I think a ordinary read operator like old := m.state in concurrent 
> environment is not safe,it may read a unexpected value.
>
> I wonder whether the oridinary read operation is right? Could you help me? 
> Thanks in advance.
>
> I'm very sorry to disturb you...

When reading or writing a value that is the size of a memory word or
smaller and is aligned such that the value does not cross a word
boundary in memory Go assumes that the entire value will always be
read or written as a unit.  This is true of all processors that Go
currently supports.

The purpose of an atomic operation is different: it is about when the
value is visible to other cores on the same system.

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcXBFNtB8JWww3K7vKACq-mF7Lr0hquwaBWGy2S%3DgS2g5g%40mail.gmail.com.

Reply via email to