mirror of https://github.com/golang/go.git
runtime: fix writebarrier throw in lock_sema
The value in question is really a bit pattern (a pointer with extra bits thrown in), so treat it as a uintptr instead, avoiding the generation of a write barrier when there might not be a p. Also add the obligatory //go:nowritebarrier. Change-Id: I4ea097945dd7093a140f4740bcadca3ce7191971 Reviewed-on: https://go-review.googlesource.com/7667 Reviewed-by: Rick Hudson <rlh@golang.org> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
41dbcc19ef
commit
87ec06f961
|
|
@ -72,7 +72,7 @@ Loop:
|
|||
// for this lock, chained through m->nextwaitm.
|
||||
// Queue this M.
|
||||
for {
|
||||
gp.m.nextwaitm = (*m)((unsafe.Pointer)(v &^ locked))
|
||||
gp.m.nextwaitm = v &^ locked
|
||||
if casuintptr(&l.key, v, uintptr(unsafe.Pointer(gp.m))|locked) {
|
||||
break
|
||||
}
|
||||
|
|
@ -90,6 +90,8 @@ Loop:
|
|||
}
|
||||
}
|
||||
|
||||
//go:nowritebarrier
|
||||
// We might not be holding a p in this code.
|
||||
func unlock(l *mutex) {
|
||||
gp := getg()
|
||||
var mp *m
|
||||
|
|
@ -103,7 +105,7 @@ func unlock(l *mutex) {
|
|||
// Other M's are waiting for the lock.
|
||||
// Dequeue an M.
|
||||
mp = (*m)((unsafe.Pointer)(v &^ locked))
|
||||
if casuintptr(&l.key, v, uintptr(unsafe.Pointer(mp.nextwaitm))) {
|
||||
if casuintptr(&l.key, v, mp.nextwaitm) {
|
||||
// Dequeued an M. Wake it.
|
||||
semawakeup(mp)
|
||||
break
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ type m struct {
|
|||
freghi [16]uint32 // d[i] msb and f[i+16]
|
||||
fflag uint32 // floating point compare flags
|
||||
locked uint32 // tracking for lockosthread
|
||||
nextwaitm *m // next m waiting for lock
|
||||
nextwaitm uintptr // next m waiting for lock
|
||||
waitsema uintptr // semaphore for parking on locks
|
||||
waitsemacount uint32
|
||||
waitsemalock uint32
|
||||
|
|
|
|||
Loading…
Reference in New Issue