mirror of
https://github.com/golang/go
synced 2024-10-14 11:53:56 +00:00
sync: document why copyChecker checks the condition twice
Fixes #40924 Change-Id: I249a278be1ec3c67088819af4456e6c393431724
This commit is contained in:
parent
ac64a3628b
commit
772c7ae7e1
|
@ -96,6 +96,10 @@ func (c *Cond) Broadcast() {
|
||||||
type copyChecker uintptr
|
type copyChecker uintptr
|
||||||
|
|
||||||
func (c *copyChecker) check() {
|
func (c *copyChecker) check() {
|
||||||
|
// Check if c has been copied in three steps:
|
||||||
|
// 1. The first comparison is the fast-path. If c has been initialized and not copied, this will return immediately. Otherwise, c is either not initialized, or has been copied.
|
||||||
|
// 2. Ensure c is initialized. If the CAS succeeds, we're done. If it fails, c was either initialized concurrently and we simply lost the race, or c has been copied.
|
||||||
|
// 3. Do step 1 again. Now that c is definitely initialized, if this fails, c was copied.
|
||||||
if uintptr(*c) != uintptr(unsafe.Pointer(c)) &&
|
if uintptr(*c) != uintptr(unsafe.Pointer(c)) &&
|
||||||
!atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.Pointer(c))) &&
|
!atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.Pointer(c))) &&
|
||||||
uintptr(*c) != uintptr(unsafe.Pointer(c)) {
|
uintptr(*c) != uintptr(unsafe.Pointer(c)) {
|
||||||
|
|
Loading…
Reference in a new issue