//go:nosplit func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool { if !atomic.Casp1((*unsafe.Pointer)(noescape(unsafe.Pointer(ptr))), noescape(old), new) { return false } writebarrierptr_nostore((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) return true }
//go:nosplit func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool { // The write barrier is only necessary if the CAS succeeds, // but since it needs to happen before the write becomes // public, we have to do it conservatively all the time. writebarrierptr_prewrite((*uintptr)(unsafe.Pointer(ptr)), uintptr(new)) return atomic.Casp1((*unsafe.Pointer)(noescape(unsafe.Pointer(ptr))), noescape(old), new) }
// bv describes the memory starting at address scanp. // Adjust any pointers contained therein. func adjustpointers(scanp unsafe.Pointer, cbv *bitvector, adjinfo *adjustinfo, f *_func) { bv := gobv(*cbv) minp := adjinfo.old.lo maxp := adjinfo.old.hi delta := adjinfo.delta num := bv.n // If this frame might contain channel receive slots, use CAS // to adjust pointers. If the slot hasn't been received into // yet, it may contain stack pointers and a concurrent send // could race with adjusting those pointers. (The sent value // itself can never contain stack pointers.) useCAS := uintptr(scanp) < adjinfo.sghi for i := uintptr(0); i < num; i++ { if stackDebug >= 4 { print(" ", add(scanp, i*sys.PtrSize), ":", ptrnames[ptrbit(&bv, i)], ":", hex(*(*uintptr)(add(scanp, i*sys.PtrSize))), " # ", i, " ", bv.bytedata[i/8], "\n") } if ptrbit(&bv, i) == 1 { pp := (*uintptr)(add(scanp, i*sys.PtrSize)) retry: p := *pp if f != nil && 0 < p && p < _PageSize && debug.invalidptr != 0 { // Looks like a junk value in a pointer slot. // Live analysis wrong? getg().m.traceback = 2 print("runtime: bad pointer in frame ", funcname(f), " at ", pp, ": ", hex(p), "\n") throw("invalid stack pointer") } if minp <= p && p < maxp { if stackDebug >= 3 { print("adjust ptr ", p, " ", funcname(f), "\n") } if useCAS { ppu := (*unsafe.Pointer)(unsafe.Pointer(pp)) if !atomic.Casp1(ppu, unsafe.Pointer(p), unsafe.Pointer(p+delta)) { goto retry } } else { *pp = p + delta } } } } }
// Here for gccgo until we port atomic_pointer.go and mgc.go. //go:nosplit func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool { if !atomic.Casp1((*unsafe.Pointer)(noescape(unsafe.Pointer(ptr))), noescape(old), new) { return false } return true }