]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: rename m.gcing to m.preemptoff and make it a string
authorAustin Clements <austin@google.com>
Fri, 30 Jan 2015 20:30:41 +0000 (15:30 -0500)
committerAustin Clements <austin@google.com>
Mon, 2 Feb 2015 19:34:51 +0000 (19:34 +0000)
m.gcing has become overloaded to mean "don't preempt this g" in
general.  Once the garbage collector is preemptible, the one thing it
*won't* mean is that we're in the garbage collector.

So, rename gcing to "preemptoff" and make it a string giving a reason
that preemption is disabled.  gcing was never set to anything but 0 or
1, so we don't have to worry about there being a stack of reasons.

Change-Id: I4337c29e8e942e7aa4f106fc29597e1b5de4ef46
Reviewed-on: https://go-review.googlesource.com/3660
Reviewed-by: Russ Cox <rsc@golang.org>
13 files changed:
src/runtime/debug.go
src/runtime/lock_futex.go
src/runtime/lock_sema.go
src/runtime/malloc.go
src/runtime/mem.go
src/runtime/mgc.go
src/runtime/mprof.go
src/runtime/panic.go
src/runtime/panic1.go
src/runtime/proc1.go
src/runtime/runtime2.go
src/runtime/stack1.go
src/runtime/trace.go

index 105b79cfefebc3d3f4cad554a76139d9ca1e49b9..3ecaac10bc1a02794619fc5364bcfa338ad87a8a 100644 (file)
@@ -24,13 +24,13 @@ func GOMAXPROCS(n int) int {
 
        semacquire(&worldsema, false)
        gp := getg()
-       gp.m.gcing = 1
+       gp.m.preemptoff = "GOMAXPROCS"
        systemstack(stoptheworld)
 
        // newprocs will be processed by starttheworld
        newprocs = int32(n)
 
-       gp.m.gcing = 0
+       gp.m.preemptoff = ""
        semrelease(&worldsema)
        systemstack(starttheworld)
        return ret
index 6e1f1e9da453069b899489a2022d447fd6bcc8e4..1765a6ce66aacda079ec449e09e2c219790bf661 100644 (file)
@@ -180,7 +180,7 @@ func notetsleep_internal(n *note, ns int64) bool {
 
 func notetsleep(n *note, ns int64) bool {
        gp := getg()
-       if gp != gp.m.g0 && gp.m.gcing == 0 {
+       if gp != gp.m.g0 && gp.m.preemptoff != "" {
                throw("notetsleep not on g0")
        }
 
index c995e084419347f55bccfb9bde053471093aac2d..47cb88335b2ed2bb23b0f48dca0d7b42029becca 100644 (file)
@@ -240,7 +240,7 @@ func notetsleep_internal(n *note, ns int64, gp *g, deadline int64) bool {
 
 func notetsleep(n *note, ns int64) bool {
        gp := getg()
-       if gp != gp.m.g0 && gp.m.gcing == 0 {
+       if gp != gp.m.g0 && gp.m.preemptoff != "" {
                throw("notetsleep not on g0")
        }
        if gp.m.waitsema == 0 {
index ea1dd6ea499a22549a55890b70feeee05ea8a2c3..b8b1f4ed36b528f4043f245c9aaa98214b8c8914 100644 (file)
@@ -362,7 +362,7 @@ func gcwork(force int32) {
        // Ok, we're doing it!  Stop everybody else
 
        mp := acquirem()
-       mp.gcing = 1
+       mp.preemptoff = "gcing"
        releasem(mp)
        gctimer.count++
        if force == 0 {
@@ -443,7 +443,7 @@ func gcwork(force int32) {
        }
 
        // all done
-       mp.gcing = 0
+       mp.preemptoff = ""
 
        if force == 0 {
                gctimer.cycle.sweep = nanotime()
index e74ad7163d2f913d91daf48d72dceac7b87bc35c..c145886eed7e9176fe4fe8e0ad32dd67f98c77d6 100644 (file)
@@ -81,14 +81,14 @@ func ReadMemStats(m *MemStats) {
        // a pending garbage collection already calling it.
        semacquire(&worldsema, false)
        gp := getg()
-       gp.m.gcing = 1
+       gp.m.preemptoff = "read mem stats"
        systemstack(stoptheworld)
 
        systemstack(func() {
                readmemstats_m(m)
        })
 
-       gp.m.gcing = 0
+       gp.m.preemptoff = ""
        gp.m.locks++
        semrelease(&worldsema)
        systemstack(starttheworld)
@@ -99,14 +99,14 @@ func ReadMemStats(m *MemStats) {
 func runtime_debug_WriteHeapDump(fd uintptr) {
        semacquire(&worldsema, false)
        gp := getg()
-       gp.m.gcing = 1
+       gp.m.preemptoff = "write heap dump"
        systemstack(stoptheworld)
 
        systemstack(func() {
                writeheapdump_m(fd)
        })
 
-       gp.m.gcing = 0
+       gp.m.preemptoff = ""
        gp.m.locks++
        semrelease(&worldsema)
        systemstack(starttheworld)
index 01f02f26bd9665218f5a400be06927005f1089b4..75b1e5291616a0fc4b7bcf8ee049cb9335679bc9 100644 (file)
@@ -143,12 +143,12 @@ var gcpercent int32
 // The procedure is:
 //
 //     semacquire(&worldsema);
-//     m.gcing = 1;
+//     m.preemptoff = "reason";
 //     stoptheworld();
 //
 //     ... do stuff ...
 //
-//     m.gcing = 0;
+//     m.preemptoff = "";
 //     semrelease(&worldsema);
 //     starttheworld();
 //
index 7f9b6671f7740170e7a6ae09af0adea4da607980..df7093a004ae2969df5ecfb5262179e3c47c1621 100644 (file)
@@ -522,7 +522,7 @@ func GoroutineProfile(p []StackRecord) (n int, ok bool) {
        if n <= len(p) {
                gp := getg()
                semacquire(&worldsema, false)
-               gp.m.gcing = 1
+               gp.m.preemptoff = "profile"
                systemstack(stoptheworld)
 
                n = NumGoroutine()
@@ -544,7 +544,7 @@ func GoroutineProfile(p []StackRecord) (n int, ok bool) {
                        }
                }
 
-               gp.m.gcing = 0
+               gp.m.preemptoff = ""
                semrelease(&worldsema)
                systemstack(starttheworld)
        }
@@ -567,7 +567,7 @@ func Stack(buf []byte, all bool) int {
        if all {
                semacquire(&worldsema, false)
                gp := getg()
-               gp.m.gcing = 1
+               gp.m.preemptoff = "stack trace"
                systemstack(stoptheworld)
        }
 
@@ -591,7 +591,7 @@ func Stack(buf []byte, all bool) int {
 
        if all {
                gp := getg()
-               gp.m.gcing = 0
+               gp.m.preemptoff = ""
                semrelease(&worldsema)
                systemstack(starttheworld)
        }
index 09278afbed6c5ecb00683f80598db145d166653f..e2a5c629dada2301c9e3ecdf8688585e45eb0a5d 100644 (file)
@@ -353,11 +353,14 @@ func gopanic(e interface{}) {
                print("\n")
                throw("panic during malloc")
        }
-       if gp.m.gcing != 0 {
+       if gp.m.preemptoff != "" {
                print("panic: ")
                printany(e)
                print("\n")
-               throw("panic during gc")
+               print("preempt off reason: ")
+               print(gp.m.preemptoff)
+               print("\n")
+               throw("panic during preemptoff")
        }
        if gp.m.locks != 0 {
                print("panic: ")
index 880c3bac9ba8a497251a7381b32f5571abd7366c..4c0eb405859d201867aabfc1df6f3bff94ec9a41 100644 (file)
@@ -135,7 +135,7 @@ func canpanic(gp *g) bool {
        if gp == nil || gp != _m_.curg {
                return false
        }
-       if _m_.locks-_m_.softfloat != 0 || _m_.mallocing != 0 || _m_.throwing != 0 || _m_.gcing != 0 || _m_.dying != 0 {
+       if _m_.locks-_m_.softfloat != 0 || _m_.mallocing != 0 || _m_.throwing != 0 || _m_.preemptoff != "" || _m_.dying != 0 {
                return false
        }
        status := readgstatus(gp)
index 82fc41d5b319c610722bc2b891a6cca451b5103f..8f5aaa863051cc741343c4de12073b1f0feadeb6 100644 (file)
@@ -2462,7 +2462,7 @@ func sigprof(pc *uint8, sp *uint8, lr *uint8, gp *g, mp *m) {
                                pc = (*uint8)(unsafe.Pointer(uintptr(funcPC(_ExternalCode) + _PCQuantum)))
                        }
                        stk[0] = uintptr(unsafe.Pointer(pc))
-                       if mp.gcing != 0 || mp.helpgc != 0 {
+                       if mp.preemptoff != "" || mp.helpgc != 0 {
                                stk[1] = funcPC(_GC) + _PCQuantum
                        } else {
                                stk[1] = funcPC(_System) + _PCQuantum
@@ -3021,7 +3021,7 @@ func schedtrace(detailed bool) {
                if lockedg != nil {
                        id3 = lockedg.goid
                }
-               print("  M", mp.id, ": p=", id1, " curg=", id2, " mallocing=", mp.mallocing, " throwing=", mp.throwing, " gcing=", mp.gcing, ""+" locks=", mp.locks, " dying=", mp.dying, " helpgc=", mp.helpgc, " spinning=", mp.spinning, " blocked=", getg().m.blocked, " lockedg=", id3, "\n")
+               print("  M", mp.id, ": p=", id1, " curg=", id2, " mallocing=", mp.mallocing, " throwing=", mp.throwing, " preemptoff=", mp.preemptoff, ""+" locks=", mp.locks, " dying=", mp.dying, " helpgc=", mp.helpgc, " spinning=", mp.spinning, " blocked=", getg().m.blocked, " lockedg=", id3, "\n")
        }
 
        lock(&allglock)
index f6b7802de34943a93e1024408ba1f5572a3b6a56..fd448901a67cbae79403965d027c1ddf018c5522 100644 (file)
@@ -244,7 +244,7 @@ type m struct {
        id            int32
        mallocing     int32
        throwing      int32
-       gcing         int32
+       preemptoff    string // if != "", keep curg running on this m
        locks         int32
        softfloat     int32
        dying         int32
index dda39ce48181984522d41f90044b6061108747a2..8ad331777cf4f18035335fba43371366f1c7f3e2 100644 (file)
@@ -208,7 +208,7 @@ func stackalloc(n uint32) stack {
                }
                var x gclinkptr
                c := thisg.m.mcache
-               if c == nil || thisg.m.gcing != 0 || thisg.m.helpgc != 0 {
+               if c == nil || thisg.m.preemptoff != "" || thisg.m.helpgc != 0 {
                        // c == nil can happen in the guts of exitsyscall or
                        // procresize. Just get a stack from the global pool.
                        // Also don't touch stackcache during gc
@@ -271,7 +271,7 @@ func stackfree(stk stack) {
                }
                x := gclinkptr(v)
                c := gp.m.mcache
-               if c == nil || gp.m.gcing != 0 || gp.m.helpgc != 0 {
+               if c == nil || gp.m.preemptoff != "" || gp.m.helpgc != 0 {
                        lock(&stackpoolmu)
                        stackpoolfree(x, order)
                        unlock(&stackpoolmu)
@@ -648,7 +648,8 @@ func newstack() {
 
        // Be conservative about where we preempt.
        // We are interested in preempting user Go code, not runtime code.
-       // If we're holding locks, mallocing, or GCing, don't preempt.
+       // If we're holding locks, mallocing, or preemption is disabled, don't
+       // preempt.
        // This check is very early in newstack so that even the status change
        // from Grunning to Gwaiting and back doesn't happen in this case.
        // That status change by itself can be viewed as a small preemption,
@@ -658,7 +659,7 @@ func newstack() {
        // it needs a lock held by the goroutine), that small preemption turns
        // into a real deadlock.
        if preempt {
-               if thisg.m.locks != 0 || thisg.m.mallocing != 0 || thisg.m.gcing != 0 || thisg.m.p.status != _Prunning {
+               if thisg.m.locks != 0 || thisg.m.mallocing != 0 || thisg.m.preemptoff != "" || thisg.m.p.status != _Prunning {
                        // Let the goroutine keep running for now.
                        // gp->preempt is set, so it will be preempted next time.
                        gp.stackguard0 = gp.stack.lo + _StackGuard
index 7da588b5e61be5e66cac645cee48466948518099..5b168c7bfc95816719489aa7ec4639685e40a0fc 100644 (file)
@@ -121,7 +121,7 @@ func StartTrace() error {
        // of all goroutines at the beginning of the trace.
        semacquire(&worldsema, false)
        _g_ := getg()
-       _g_.m.gcing = 1
+       _g_.m.preemptoff = "start tracing"
        systemstack(stoptheworld)
 
        // We are in stop-the-world, but syscalls can finish and write to trace concurrently.
@@ -133,7 +133,7 @@ func StartTrace() error {
 
        if trace.enabled || trace.shutdown {
                unlock(&trace.bufLock)
-               _g_.m.gcing = 0
+               _g_.m.preemptoff = ""
                semrelease(&worldsema)
                systemstack(starttheworld)
                return errorString("tracing is already enabled")
@@ -162,7 +162,7 @@ func StartTrace() error {
 
        unlock(&trace.bufLock)
 
-       _g_.m.gcing = 0
+       _g_.m.preemptoff = ""
        semrelease(&worldsema)
        systemstack(starttheworld)
        return nil
@@ -175,7 +175,7 @@ func StopTrace() {
        // and also to avoid races with traceEvent.
        semacquire(&worldsema, false)
        _g_ := getg()
-       _g_.m.gcing = 1
+       _g_.m.preemptoff = "stop tracing"
        systemstack(stoptheworld)
 
        // See the comment in StartTrace.
@@ -183,7 +183,7 @@ func StopTrace() {
 
        if !trace.enabled {
                unlock(&trace.bufLock)
-               _g_.m.gcing = 0
+               _g_.m.preemptoff = ""
                semrelease(&worldsema)
                systemstack(starttheworld)
                return
@@ -224,7 +224,7 @@ func StopTrace() {
 
        unlock(&trace.bufLock)
 
-       _g_.m.gcing = 0
+       _g_.m.preemptoff = ""
        semrelease(&worldsema)
        systemstack(starttheworld)