]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: convert g.atomicstatus to internal atomic type
authorAndy Pan <panjf2000@gmail.com>
Wed, 24 Aug 2022 19:27:02 +0000 (03:27 +0800)
committerDaniel Martí <mvdan@mvdan.cc>
Mon, 5 Sep 2022 07:14:08 +0000 (07:14 +0000)
Note that this changes some unsynchronized operations of g.atomicstatus to synchronized operations.

Updates #53821

Change-Id: If249d62420ea09fbec39b570942f96c63669c333
Reviewed-on: https://go-review.googlesource.com/c/go/+/425363
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
src/runtime/export_debug_test.go
src/runtime/proc.go
src/runtime/runtime-gdb.py
src/runtime/runtime2.go

index 09e9779696b845af2c12c560d1998ffb46333730..2d8a1334093192bea20b78c3f0dc6072f0799e15 100644 (file)
@@ -109,7 +109,7 @@ func (h *debugCallHandler) inject(info *siginfo, ctxt *sigctxt, gp2 *g) bool {
        // a signal handler. Add the go:nowritebarrierrec annotation and restructure
        // this to avoid write barriers.
 
-       switch h.gp.atomicstatus {
+       switch h.gp.atomicstatus.Load() {
        case _Grunning:
                if getg().m != h.mp {
                        println("trap on wrong M", getg().m, h.mp)
index 6ecb786d1b053c12efe7a170dc6ff68550399ba0..49f2caceacfe24f0a43d68c0e3cc7d5af643b1bf 100644 (file)
@@ -899,7 +899,7 @@ func freezetheworld() {
 //
 //go:nosplit
 func readgstatus(gp *g) uint32 {
-       return atomic.Load(&gp.atomicstatus)
+       return gp.atomicstatus.Load()
 }
 
 // The Gscanstatuses are acting like locks and this releases them.
@@ -921,7 +921,7 @@ func casfrom_Gscanstatus(gp *g, oldval, newval uint32) {
                _Gscansyscall,
                _Gscanpreempted:
                if newval == oldval&^_Gscan {
-                       success = atomic.Cas(&gp.atomicstatus, oldval, newval)
+                       success = gp.atomicstatus.CompareAndSwap(oldval, newval)
                }
        }
        if !success {
@@ -941,7 +941,7 @@ func castogscanstatus(gp *g, oldval, newval uint32) bool {
                _Gwaiting,
                _Gsyscall:
                if newval == oldval|_Gscan {
-                       r := atomic.Cas(&gp.atomicstatus, oldval, newval)
+                       r := gp.atomicstatus.CompareAndSwap(oldval, newval)
                        if r {
                                acquireLockRank(lockRankGscan)
                        }
@@ -977,15 +977,15 @@ func casgstatus(gp *g, oldval, newval uint32) {
 
        // loop if gp->atomicstatus is in a scan state giving
        // GC time to finish and change the state to oldval.
-       for i := 0; !atomic.Cas(&gp.atomicstatus, oldval, newval); i++ {
-               if oldval == _Gwaiting && gp.atomicstatus == _Grunnable {
+       for i := 0; !gp.atomicstatus.CompareAndSwap(oldval, newval); i++ {
+               if oldval == _Gwaiting && gp.atomicstatus.Load() == _Grunnable {
                        throw("casgstatus: waiting for Gwaiting but is Grunnable")
                }
                if i == 0 {
                        nextYield = nanotime() + yieldDelay
                }
                if nanotime() < nextYield {
-                       for x := 0; x < 10 && gp.atomicstatus != oldval; x++ {
+                       for x := 0; x < 10 && gp.atomicstatus.Load() != oldval; x++ {
                                procyield(1)
                        }
                } else {
@@ -1040,7 +1040,7 @@ func casgcopystack(gp *g) uint32 {
                if oldstatus != _Gwaiting && oldstatus != _Grunnable {
                        throw("copystack: bad status, not Gwaiting or Grunnable")
                }
-               if atomic.Cas(&gp.atomicstatus, oldstatus, _Gcopystack) {
+               if gp.atomicstatus.CompareAndSwap(oldstatus, _Gcopystack) {
                        return oldstatus
                }
        }
@@ -1055,7 +1055,7 @@ func casGToPreemptScan(gp *g, old, new uint32) {
                throw("bad g transition")
        }
        acquireLockRank(lockRankGscan)
-       for !atomic.Cas(&gp.atomicstatus, _Grunning, _Gscan|_Gpreempted) {
+       for !gp.atomicstatus.CompareAndSwap(_Grunning, _Gscan|_Gpreempted) {
        }
 }
 
@@ -1066,7 +1066,7 @@ func casGFromPreempted(gp *g, old, new uint32) bool {
        if old != _Gpreempted || new != _Gwaiting {
                throw("bad g transition")
        }
-       return atomic.Cas(&gp.atomicstatus, _Gpreempted, _Gwaiting)
+       return gp.atomicstatus.CompareAndSwap(_Gpreempted, _Gwaiting)
 }
 
 // stopTheWorld stops all P's from executing goroutines, interrupting
index 5bb605cc37b567abfd90457b24be15718fb27b6a..c4462de851a24c4bca75722746e8d853582734d1 100644 (file)
@@ -447,7 +447,7 @@ class GoroutinesCmd(gdb.Command):
                # args = gdb.string_to_argv(arg)
                vp = gdb.lookup_type('void').pointer()
                for ptr in SliceValue(gdb.parse_and_eval("'runtime.allgs'")):
-                       if ptr['atomicstatus'] == G_DEAD:
+                       if ptr['atomicstatus']['value'] == G_DEAD:
                                continue
                        s = ' '
                        if ptr['m']:
@@ -455,7 +455,7 @@ class GoroutinesCmd(gdb.Command):
                        pc = ptr['sched']['pc'].cast(vp)
                        pc = pc_to_int(pc)
                        blk = gdb.block_for_pc(pc)
-                       status = int(ptr['atomicstatus'])
+                       status = int(ptr['atomicstatus']['value'])
                        st = sts.get(status, "unknown(%d)" % status)
                        print(s, ptr['goid'], "{0:8s}".format(st), blk.function)
 
@@ -472,7 +472,7 @@ def find_goroutine(goid):
        """
        vp = gdb.lookup_type('void').pointer()
        for ptr in SliceValue(gdb.parse_and_eval("'runtime.allgs'")):
-               if ptr['atomicstatus'] == G_DEAD:
+               if ptr['atomicstatus']['value'] == G_DEAD:
                        continue
                if ptr['goid'] == goid:
                        break
@@ -480,7 +480,7 @@ def find_goroutine(goid):
                return None, None
        # Get the goroutine's saved state.
        pc, sp = ptr['sched']['pc'], ptr['sched']['sp']
-       status = ptr['atomicstatus']&~G_SCAN
+       status = ptr['atomicstatus']['value']&~G_SCAN
        # Goroutine is not running nor in syscall, so use the info in goroutine
        if status != G_RUNNING and status != G_SYSCALL:
                return pc.cast(vp), sp.cast(vp)
index f9bdb8e23676b0d194b52fa0837462ab97e94579..40d3805808819785d003c051c75adbf2fb2bf066 100644 (file)
@@ -435,7 +435,7 @@ type g struct {
        // 3. By debugCallWrap to pass parameters to a new goroutine because allocating a
        //    closure in the runtime is forbidden.
        param        unsafe.Pointer
-       atomicstatus uint32
+       atomicstatus atomic.Uint32
        stackLock    uint32 // sigprof/scang lock; TODO: fold in to atomicstatus
        goid         uint64
        schedlink    guintptr