]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/runtime/proc1.go
[dev.garbage] all: merge dev.cc into dev.garbage
[gostls13.git] / src / runtime / proc1.go
index 81b211d0d35039a0b5c4099a04a63722ec1c326f..8c941dd35dc47d1b1d34e3dfe17ad9fbcedb7975 100644 (file)
@@ -371,13 +371,6 @@ 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 !cas(&gp.atomicstatus, oldval, newval) {
-               // Help GC if needed.
-               if gp.preemptscan && !gp.gcworkdone && (oldval == _Grunning || oldval == _Gsyscall) {
-                       gp.preemptscan = false
-                       systemstack(func() {
-                               gcphasework(gp)
-                       })
-               }
        }
 }
 
@@ -424,6 +417,13 @@ func stopg(gp *g) bool {
                        return false
 
                case _Grunning:
+                       if gcphase == _GCscan {
+                               // Running routines not scanned during
+                               // GCscan phase, we only scan non-running routines.
+                               gp.gcworkdone = true
+                               return false
+                       }
+
                        // Claim goroutine, so we aren't racing with a status
                        // transition away from Grunning.
                        if !castogscanstatus(gp, _Grunning, _Gscanrunning) {
@@ -489,9 +489,10 @@ func stopscanstart(gp *g) {
 
 // Runs on g0 and does the actual work after putting the g back on the run queue.
 func mquiesce(gpmaster *g) {
-       activeglen := len(allgs)
        // enqueue the calling goroutine.
        restartg(gpmaster)
+
+       activeglen := len(allgs)
        for i := 0; i < activeglen; i++ {
                gp := allgs[i]
                if readgstatus(gp) == _Gdead {
@@ -1556,7 +1557,8 @@ func save(pc, sp uintptr) {
        _g_.sched.lr = 0
        _g_.sched.ret = 0
        _g_.sched.ctxt = nil
-       _g_.sched.g = _g_
+       // write as uintptr to avoid write barrier, which will smash _g_.sched.
+       *(*uintptr)(unsafe.Pointer(&_g_.sched.g)) = uintptr(unsafe.Pointer(_g_))
 }
 
 // The goroutine g is about to enter a system call.
@@ -1602,7 +1604,10 @@ func reentersyscall(pc, sp uintptr) {
        _g_.syscallpc = pc
        casgstatus(_g_, _Grunning, _Gsyscall)
        if _g_.syscallsp < _g_.stack.lo || _g_.stack.hi < _g_.syscallsp {
-               systemstack(entersyscall_bad)
+               systemstack(func() {
+                       print("entersyscall inconsistent ", hex(_g_.syscallsp), " [", hex(_g_.stack.lo), ",", hex(_g_.stack.hi), "]\n")
+                       gothrow("entersyscall")
+               })
        }
 
        if atomicload(&sched.sysmonwait) != 0 { // TODO: fast atomic
@@ -1631,13 +1636,6 @@ func entersyscall(dummy int32) {
        reentersyscall(getcallerpc(unsafe.Pointer(&dummy)), getcallersp(unsafe.Pointer(&dummy)))
 }
 
-func entersyscall_bad() {
-       var gp *g
-       gp = getg().m.curg
-       print("entersyscall inconsistent ", hex(gp.syscallsp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n")
-       gothrow("entersyscall")
-}
-
 func entersyscall_sysmon() {
        lock(&sched.lock)
        if atomicload(&sched.sysmonwait) != 0 {
@@ -1669,12 +1667,26 @@ func entersyscallblock(dummy int32) {
        _g_.stackguard0 = stackPreempt // see comment in entersyscall
 
        // Leave SP around for GC and traceback.
-       save(getcallerpc(unsafe.Pointer(&dummy)), getcallersp(unsafe.Pointer(&dummy)))
+       pc := getcallerpc(unsafe.Pointer(&dummy))
+       sp := getcallersp(unsafe.Pointer(&dummy))
+       save(pc, sp)
        _g_.syscallsp = _g_.sched.sp
        _g_.syscallpc = _g_.sched.pc
+       if _g_.syscallsp < _g_.stack.lo || _g_.stack.hi < _g_.syscallsp {
+               sp1 := sp
+               sp2 := _g_.sched.sp
+               sp3 := _g_.syscallsp
+               systemstack(func() {
+                       print("entersyscallblock inconsistent ", hex(sp1), " ", hex(sp2), " ", hex(sp3), " [", hex(_g_.stack.lo), ",", hex(_g_.stack.hi), "]\n")
+                       gothrow("entersyscallblock")
+               })
+       }
        casgstatus(_g_, _Grunning, _Gsyscall)
        if _g_.syscallsp < _g_.stack.lo || _g_.stack.hi < _g_.syscallsp {
-               systemstack(entersyscall_bad)
+               systemstack(func() {
+                       print("entersyscallblock inconsistent ", hex(sp), " ", hex(_g_.sched.sp), " ", hex(_g_.syscallsp), " [", hex(_g_.stack.lo), ",", hex(_g_.stack.hi), "]\n")
+                       gothrow("entersyscallblock")
+               })
        }
 
        systemstack(entersyscallblock_handoff)
@@ -1753,6 +1765,7 @@ func exitsyscallfast() bool {
 
        // Freezetheworld sets stopwait but does not retake P's.
        if sched.stopwait != 0 {
+               _g_.m.mcache = nil
                _g_.m.p = nil
                return false
        }
@@ -1766,6 +1779,7 @@ func exitsyscallfast() bool {
        }
 
        // Try to get any other idle P.
+       _g_.m.mcache = nil
        _g_.m.p = nil
        if sched.pidle != nil {
                var ok bool
@@ -2340,6 +2354,8 @@ func setcpuprofilerate_m(hz int32) {
 }
 
 // Change number of processors.  The world is stopped, sched is locked.
+// gcworkbufs are not being modified by either the GC or
+// the write barrier code.
 func procresize(new int32) {
        old := gomaxprocs
        if old < 0 || old > _MaxGomaxprocs || new <= 0 || new > _MaxGomaxprocs {