OLD | NEW |
1 // Copyright 2013 The Go Authors. All rights reserved. | 1 // Copyright 2013 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 #include "runtime.h" |
6 #include "arch_GOARCH.h" | 6 #include "arch_GOARCH.h" |
7 #include "malloc.h" | 7 #include "malloc.h" |
8 #include "stack.h" | 8 #include "stack.h" |
9 #include "funcdata.h" | 9 #include "funcdata.h" |
10 #include "typekind.h" | 10 #include "typekind.h" |
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 runtime·throw("runtime: stack growth argsize"); | 920 runtime·throw("runtime: stack growth argsize"); |
921 } | 921 } |
922 | 922 |
923 if(gp->stackguard0 == (uintptr)StackPreempt) { | 923 if(gp->stackguard0 == (uintptr)StackPreempt) { |
924 if(gp == g->m->g0) | 924 if(gp == g->m->g0) |
925 runtime·throw("runtime: preempt g0"); | 925 runtime·throw("runtime: preempt g0"); |
926 if(oldstatus == Grunning && g->m->p == nil && g->m->locks == 0) | 926 if(oldstatus == Grunning && g->m->p == nil && g->m->locks == 0) |
927 runtime·throw("runtime: g is running but p is not"); | 927 runtime·throw("runtime: g is running but p is not"); |
928 if(oldstatus == Gsyscall && g->m->locks == 0) | 928 if(oldstatus == Gsyscall && g->m->locks == 0) |
929 runtime·throw("runtime: stack growth during syscall"); | 929 runtime·throw("runtime: stack growth during syscall"); |
| 930 if(oldstatus == Grunning && gp->preemptscan) { |
| 931 runtime·gcphasework(gp); |
| 932 runtime·casgstatus(gp, Gwaiting, Grunning); |
| 933 gp->stackguard0 = gp->stackguard; |
| 934 gp->preempt = false;· |
| 935 gp->preemptscan = false; // Tells the GC premptio
n was successful. |
| 936 runtime·gogo(&gp->sched); // never return· |
| 937 } |
930 | 938 |
931 // Be conservative about where we preempt. | 939 // Be conservative about where we preempt. |
932 // We are interested in preempting user Go code, not runtime cod
e. | 940 // We are interested in preempting user Go code, not runtime cod
e. |
933 if(oldstatus != Grunning || g->m->locks || g->m->mallocing || g-
>m->gcing || g->m->p->status != Prunning) { | 941 if(oldstatus != Grunning || g->m->locks || g->m->mallocing || g-
>m->gcing || g->m->p->status != Prunning) { |
934 // Let the goroutine keep running for now. | 942 // Let the goroutine keep running for now. |
935 // gp->preempt is set, so it will be preempted next time
. | 943 // gp->preempt is set, so it will be preempted next time
. |
936 gp->stackguard0 = gp->stackguard; | 944 gp->stackguard0 = gp->stackguard; |
937 runtime·casgstatus(gp, Gwaiting, oldstatus); // oldstatu
s is Gsyscall or Grunning | 945 runtime·casgstatus(gp, Gwaiting, oldstatus); // oldstatu
s is Gsyscall or Grunning |
938 runtime·gogo(&gp->sched); // never return | 946 runtime·gogo(&gp->sched); // never return |
939 } | 947 } |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 if(gp->m != nil && gp->m->libcallsp != 0) | 1106 if(gp->m != nil && gp->m->libcallsp != 0) |
1099 return; | 1107 return; |
1100 #endif | 1108 #endif |
1101 if(StackDebug > 0) | 1109 if(StackDebug > 0) |
1102 runtime·printf("shrinking stack %D->%D\n", (uint64)oldsize, (uin
t64)newsize); | 1110 runtime·printf("shrinking stack %D->%D\n", (uint64)oldsize, (uin
t64)newsize); |
1103 nframes = copyabletopsegment(gp); | 1111 nframes = copyabletopsegment(gp); |
1104 if(nframes == -1) | 1112 if(nframes == -1) |
1105 return; | 1113 return; |
1106 copystack(gp, nframes, newsize); | 1114 copystack(gp, nframes, newsize); |
1107 } | 1115 } |
OLD | NEW |