OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 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 "race.h" | 9 #include "race.h" |
10 #include "type.h" | 10 #include "type.h" |
(...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 // not from the low-level system calls used by the runtime. | 1229 // not from the low-level system calls used by the runtime. |
1230 // | 1230 // |
1231 // Entersyscall cannot split the stack: the runtime·gosave must | 1231 // Entersyscall cannot split the stack: the runtime·gosave must |
1232 // make g->sched refer to the caller's stack segment, because | 1232 // make g->sched refer to the caller's stack segment, because |
1233 // entersyscall is going to return immediately after. | 1233 // entersyscall is going to return immediately after. |
1234 // It's okay to call matchmg and notewakeup even after | 1234 // It's okay to call matchmg and notewakeup even after |
1235 // decrementing mcpu, because we haven't released the | 1235 // decrementing mcpu, because we haven't released the |
1236 // sched lock yet, so the garbage collector cannot be running. | 1236 // sched lock yet, so the garbage collector cannot be running. |
1237 #pragma textflag 7 | 1237 #pragma textflag 7 |
1238 void | 1238 void |
1239 runtime·entersyscall(void) | 1239 ·entersyscall(int32 dummy) |
1240 { | 1240 { |
1241 uint32 v; | 1241 uint32 v; |
1242 | 1242 |
1243 if(m->profilehz > 0) | 1243 if(m->profilehz > 0) |
1244 runtime·setprof(false); | 1244 runtime·setprof(false); |
1245 | 1245 |
1246 // Leave SP around for gc and traceback. | 1246 // Leave SP around for gc and traceback. |
1247 » runtime·gosave(&g->sched); | 1247 » g->sched.sp = (uintptr)runtime·getcallersp(&dummy); |
| 1248 » g->sched.pc = runtime·getcallerpc(&dummy); |
| 1249 » g->sched.g = g; |
1248 g->gcsp = g->sched.sp; | 1250 g->gcsp = g->sched.sp; |
| 1251 g->gcpc = g->sched.pc; |
1249 g->gcstack = g->stackbase; | 1252 g->gcstack = g->stackbase; |
1250 g->gcguard = g->stackguard; | 1253 g->gcguard = g->stackguard; |
1251 g->status = Gsyscall; | 1254 g->status = Gsyscall; |
1252 if(g->gcsp < g->gcguard-StackGuard || g->gcstack < g->gcsp) { | 1255 if(g->gcsp < g->gcguard-StackGuard || g->gcstack < g->gcsp) { |
1253 // runtime·printf("entersyscall inconsistent %p [%p,%p]\n", | 1256 // runtime·printf("entersyscall inconsistent %p [%p,%p]\n", |
1254 // g->gcsp, g->gcguard-StackGuard, g->gcstack); | 1257 // g->gcsp, g->gcguard-StackGuard, g->gcstack); |
1255 runtime·throw("entersyscall"); | 1258 runtime·throw("entersyscall"); |
1256 } | 1259 } |
1257 | 1260 |
1258 // Fast path. | 1261 // Fast path. |
(...skipping 23 matching lines...) Expand all Loading... |
1282 // (notewakeup, matchmg) triggered something using it. | 1285 // (notewakeup, matchmg) triggered something using it. |
1283 runtime·gosave(&g->sched); | 1286 runtime·gosave(&g->sched); |
1284 | 1287 |
1285 schedunlock(); | 1288 schedunlock(); |
1286 } | 1289 } |
1287 | 1290 |
1288 // The same as runtime·entersyscall(), but with a hint that the syscall is block
ing. | 1291 // The same as runtime·entersyscall(), but with a hint that the syscall is block
ing. |
1289 // The hint is ignored at the moment, and it's just a copy of runtime·entersysca
ll(). | 1292 // The hint is ignored at the moment, and it's just a copy of runtime·entersysca
ll(). |
1290 #pragma textflag 7 | 1293 #pragma textflag 7 |
1291 void | 1294 void |
1292 runtime·entersyscallblock(void) | 1295 ·entersyscallblock(int32 dummy) |
1293 { | 1296 { |
1294 uint32 v; | 1297 uint32 v; |
1295 | 1298 |
1296 if(m->profilehz > 0) | 1299 if(m->profilehz > 0) |
1297 runtime·setprof(false); | 1300 runtime·setprof(false); |
1298 | 1301 |
1299 // Leave SP around for gc and traceback. | 1302 // Leave SP around for gc and traceback. |
1300 » runtime·gosave(&g->sched); | 1303 » g->sched.sp = (uintptr)runtime·getcallersp(&dummy); |
| 1304 » g->sched.pc = runtime·getcallerpc(&dummy); |
| 1305 » g->sched.g = g; |
1301 g->gcsp = g->sched.sp; | 1306 g->gcsp = g->sched.sp; |
| 1307 g->gcpc = g->sched.pc; |
1302 g->gcstack = g->stackbase; | 1308 g->gcstack = g->stackbase; |
1303 g->gcguard = g->stackguard; | 1309 g->gcguard = g->stackguard; |
1304 g->status = Gsyscall; | 1310 g->status = Gsyscall; |
1305 if(g->gcsp < g->gcguard-StackGuard || g->gcstack < g->gcsp) { | 1311 if(g->gcsp < g->gcguard-StackGuard || g->gcstack < g->gcsp) { |
1306 » » // runtime·printf("entersyscall inconsistent %p [%p,%p]\n", | 1312 » » // runtime·printf("entersyscallblock inconsistent %p [%p,%p]\n", |
1307 // g->gcsp, g->gcguard-StackGuard, g->gcstack); | 1313 // g->gcsp, g->gcguard-StackGuard, g->gcstack); |
1308 » » runtime·throw("entersyscall"); | 1314 » » runtime·throw("entersyscallblock"); |
1309 } | 1315 } |
1310 | 1316 |
1311 // Fast path. | 1317 // Fast path. |
1312 // The slow path inside the schedlock/schedunlock will get | 1318 // The slow path inside the schedlock/schedunlock will get |
1313 // through without stopping if it does: | 1319 // through without stopping if it does: |
1314 // mcpu-- | 1320 // mcpu-- |
1315 // gwait not true | 1321 // gwait not true |
1316 // waitstop && mcpu <= mcpumax not true | 1322 // waitstop && mcpu <= mcpumax not true |
1317 // If we can do the same with a single atomic add, | 1323 // If we can do the same with a single atomic add, |
1318 // then we can skip the locks. | 1324 // then we can skip the locks. |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1719 if(!Windows && (m == nil || m->mcache == nil)) | 1725 if(!Windows && (m == nil || m->mcache == nil)) |
1720 return; | 1726 return; |
1721 if(prof.fn == nil || prof.hz == 0) | 1727 if(prof.fn == nil || prof.hz == 0) |
1722 return; | 1728 return; |
1723 | 1729 |
1724 runtime·lock(&prof); | 1730 runtime·lock(&prof); |
1725 if(prof.fn == nil) { | 1731 if(prof.fn == nil) { |
1726 runtime·unlock(&prof); | 1732 runtime·unlock(&prof); |
1727 return; | 1733 return; |
1728 } | 1734 } |
1729 » n = runtime·gentraceback(pc, sp, lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf
)); | 1735 » n = runtime·gentraceback(pc, sp, lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf
), nil, nil); |
1730 if(n > 0) | 1736 if(n > 0) |
1731 prof.fn(prof.pcbuf, n); | 1737 prof.fn(prof.pcbuf, n); |
1732 runtime·unlock(&prof); | 1738 runtime·unlock(&prof); |
1733 } | 1739 } |
1734 | 1740 |
1735 // Arrange to call fn with a traceback hz times a second. | 1741 // Arrange to call fn with a traceback hz times a second. |
1736 void | 1742 void |
1737 runtime·setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz) | 1743 runtime·setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz) |
1738 { | 1744 { |
1739 // Force sane arguments. | 1745 // Force sane arguments. |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1965 runtime·printf("bad element %d(%d) at iter %d\n"
, j, gs[j].sig, i); | 1971 runtime·printf("bad element %d(%d) at iter %d\n"
, j, gs[j].sig, i); |
1966 runtime·throw("bad element"); | 1972 runtime·throw("bad element"); |
1967 } | 1973 } |
1968 } | 1974 } |
1969 if(s != i/2 && s != i/2+1) { | 1975 if(s != i/2 && s != i/2+1) { |
1970 runtime·printf("bad steal %d, want %d or %d, iter %d\n", | 1976 runtime·printf("bad steal %d, want %d or %d, iter %d\n", |
1971 s, i/2, i/2+1, i); | 1977 s, i/2, i/2+1, i); |
1972 runtime·throw("bad steal"); | 1978 runtime·throw("bad steal"); |
1973 } | 1979 } |
1974 } | 1980 } |
1975 } | 1981 } |
OLD | NEW |