Thanks for your reply,Ian.I've always had a misunderstanding about atomic 
operation,I thought atomic operation is only used to protect the CPU 
instructions from being interrupted.

I have watched some lectures about C++ memory order on youtube.As you 
mentioned,another function of atomic operation is to synchronize the value 
between CPU cache and memory.

As eric said, there is no need to read the latest value of mutex.state 
here.Even if the latest value of mutex.state is read by 
atomic.LoadInt32(),it may out of date when execute the CAS operation.

I leave the link of lecture here,it may help people who have the same 
confusion as me.

C++ and Beyond 2012: Herb Sutter - atomic Weapons 1 of 2 
<https://www.youtube.com/watch?v=A8eCGOqgvH4>

Arvid Norberg: The C++ memory model: an intuition 
<https://www.youtube.com/watch?v=OyNG4qiWnmU>

在2022年4月3日星期日 UTC+8 16:39:47<liweiforeveryoung> 写道:

> Thanks for your reply,eric.I've always focused on this situation,without 
> atomic operator,If goroutine A set a variable v to 0 and goroutine B set 
> the variable a to 1,anther goroutine C would probably get a unexpected 
> value which is neither 0 nor 1 when its read operation of a is 
> interrupted.So I thought the code is at risk when this happens.
>
> But I'm wrong.As Ian Lance Taylor said,Go will ensure the read operation 
> of mutex.state is a unit in this case,so what i said will never happen.And 
> as you said, the CAS operation will failed even if what i said happened.
> 在2022年4月2日星期六 UTC+8 11:55:52<[email protected]> 写道:
>
>> Why is it not safe to read here? The real write operation is done through 
>> CAS, assuming the read value is out of date, then the CAS operation will 
>> fail.
>>
>> 在2022年4月2日星期六 UTC+8 11:41:00<Ian Lance Taylor> 写道:
>>
>>> On Fri, Apr 1, 2022 at 8:31 PM 机智的小小帅 <[email protected]> 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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5141291e-fb94-4b4e-874e-8314b8076735n%40googlegroups.com.

Reply via email to