Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(121)

Delta Between Two Patch Sets: src/pkg/runtime/proc.c

Issue 5334051: code review 5334051: runtime: add timer support, use for package time (Closed)
Left Patch Set: diff -r d946ec1f09f6 https://go.googlecode.com/hg Created 13 years, 5 months ago
Right Patch Set: diff -r 9870fbad1533 https://go.googlecode.com/hg Created 13 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/runtime/plan9/thread.c ('k') | src/pkg/runtime/runtime.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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.h" 6 #include "arch.h"
7 #include "defs.h" 7 #include "defs.h"
8 #include "malloc.h" 8 #include "malloc.h"
9 #include "os.h" 9 #include "os.h"
10 #include "stack.h" 10 #include "stack.h"
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 731
732 typedef struct CgoThreadStart CgoThreadStart; 732 typedef struct CgoThreadStart CgoThreadStart;
733 struct CgoThreadStart 733 struct CgoThreadStart
734 { 734 {
735 M *m; 735 M *m;
736 G *g; 736 G *g;
737 void (*fn)(void); 737 void (*fn)(void);
738 }; 738 };
739 739
740 // Kick off new m's as needed (up to mcpumax). 740 // Kick off new m's as needed (up to mcpumax).
741 // There are already `other' other cpus that will
742 // start looking for goroutines shortly.
743 // Sched is locked. 741 // Sched is locked.
744 static void 742 static void
745 matchmg(void) 743 matchmg(void)
746 { 744 {
747 G *gp; 745 G *gp;
748 M *mp; 746 M *mp;
749 747
750 if(m->mallocing || m->gcing) 748 if(m->mallocing || m->gcing)
751 return; 749 return;
752 750
753 while(haveg() && canaddmcpu()) { 751 while(haveg() && canaddmcpu()) {
754 gp = gget(); 752 gp = gget();
755 if(gp == nil) 753 if(gp == nil)
756 runtime·throw("gget inconsistency"); 754 runtime·throw("gget inconsistency");
757 755
758 // Find the m that will run gp. 756 // Find the m that will run gp.
759 if((mp = mget(gp)) == nil) 757 if((mp = mget(gp)) == nil)
760 mp = runtime·newm(); 758 mp = runtime·newm();
761 mnextg(mp, gp); 759 mnextg(mp, gp);
762 } 760 }
763 } 761 }
764 762
763 // Create a new m. It will start off with a call to runtime·mstart.
765 M* 764 M*
766 runtime·newm(void) 765 runtime·newm(void)
767 { 766 {
768 M *m; 767 M *m;
769 768
770 m = runtime·malloc(sizeof(M)); 769 m = runtime·malloc(sizeof(M));
771 mcommoninit(m); 770 mcommoninit(m);
772 771
773 if(runtime·iscgo) { 772 if(runtime·iscgo) {
774 CgoThreadStart ts; 773 CgoThreadStart ts;
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 986
988 // Gosched returned, so we're allowed to run now. 987 // Gosched returned, so we're allowed to run now.
989 // Delete the gcstack information that we left for 988 // Delete the gcstack information that we left for
990 // the garbage collector during the system call. 989 // the garbage collector during the system call.
991 // Must wait until now because until gosched returns 990 // Must wait until now because until gosched returns
992 // we don't know for sure that the garbage collector 991 // we don't know for sure that the garbage collector
993 // is not running. 992 // is not running.
994 g->gcstack = nil; 993 g->gcstack = nil;
995 } 994 }
996 995
996 // Called from runtime·lessstack when returning from a function which
997 // allocated a new stack segment. The function's return value is in
998 // m->cret.
997 void 999 void
998 runtime·oldstack(void) 1000 runtime·oldstack(void)
999 { 1001 {
1000 Stktop *top, old; 1002 Stktop *top, old;
1001 uint32 argsize; 1003 uint32 argsize;
1002 byte *sp; 1004 byte *sp;
1003 G *g1; 1005 G *g1;
1004 int32 goid; 1006 int32 goid;
1005 1007
1006 //printf("oldstack m->cret=%p\n", m->cret); 1008 //printf("oldstack m->cret=%p\n", m->cret);
(...skipping 11 matching lines...) Expand all
1018 USED(goid); 1020 USED(goid);
1019 1021
1020 if(old.free != 0) 1022 if(old.free != 0)
1021 runtime·stackfree(g1->stackguard - StackGuard, old.free); 1023 runtime·stackfree(g1->stackguard - StackGuard, old.free);
1022 g1->stackbase = old.stackbase; 1024 g1->stackbase = old.stackbase;
1023 g1->stackguard = old.stackguard; 1025 g1->stackguard = old.stackguard;
1024 1026
1025 runtime·gogo(&old.gobuf, m->cret); 1027 runtime·gogo(&old.gobuf, m->cret);
1026 } 1028 }
1027 1029
1030 // Called from reflect·call or from runtime·morestack when a new
1031 // stack segment is needed. Allocate a new stack big enough for
1032 // m->moreframesize bytes, copy m->moreargsize bytes to the new frame,
1033 // and then act as though runtime·lessstack called the function at
1034 // m->morepc.
1028 void 1035 void
1029 runtime·newstack(void) 1036 runtime·newstack(void)
1030 { 1037 {
1031 int32 framesize, argsize; 1038 int32 framesize, argsize;
1032 Stktop *top; 1039 Stktop *top;
1033 byte *stk, *sp; 1040 byte *stk, *sp;
1034 G *g1; 1041 G *g1;
1035 Gobuf label; 1042 Gobuf label;
1036 bool reflectcall; 1043 bool reflectcall;
1037 uintptr free; 1044 uintptr free;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 // Continue as if lessstack had just called m->morepc 1112 // Continue as if lessstack had just called m->morepc
1106 // (the PC that decided to grow the stack). 1113 // (the PC that decided to grow the stack).
1107 label.sp = sp; 1114 label.sp = sp;
1108 label.pc = (byte*)runtime·lessstack; 1115 label.pc = (byte*)runtime·lessstack;
1109 label.g = m->curg; 1116 label.g = m->curg;
1110 runtime·gogocall(&label, m->morepc); 1117 runtime·gogocall(&label, m->morepc);
1111 1118
1112 *(int32*)345 = 123; // never return 1119 *(int32*)345 = 123; // never return
1113 } 1120 }
1114 1121
1122 // Hook used by runtime·malg to call runtime·stackalloc on the
1123 // scheduler stack. This exists because runtime·stackalloc insists
1124 // on being called on the scheduler stack, to avoid trying to grow
1125 // the stack while allocating a new stack segment.
1115 static void 1126 static void
1116 mstackalloc(G *gp) 1127 mstackalloc(G *gp)
1117 { 1128 {
1118 gp->param = runtime·stackalloc((uintptr)gp->param); 1129 gp->param = runtime·stackalloc((uintptr)gp->param);
1119 runtime·gogo(&gp->sched, 0); 1130 runtime·gogo(&gp->sched, 0);
1120 } 1131 }
1121 1132
1133 // Allocate a new g, with a stack big enough for stacksize bytes.
1122 G* 1134 G*
1123 runtime·malg(int32 stacksize) 1135 runtime·malg(int32 stacksize)
1124 { 1136 {
1125 G *newg; 1137 G *newg;
1126 byte *stk; 1138 byte *stk;
1127 1139
1128 newg = runtime·malloc(sizeof(G)); 1140 newg = runtime·malloc(sizeof(G));
1129 if(stacksize >= 0) { 1141 if(stacksize >= 0) {
1130 if(g == m->g0) { 1142 if(g == m->g0) {
1131 // running on scheduler stack already. 1143 // running on scheduler stack already.
1132 stk = runtime·stackalloc(StackSystem + stacksize); 1144 stk = runtime·stackalloc(StackSystem + stacksize);
1133 } else { 1145 } else {
1134 // have to call stackalloc on scheduler stack. 1146 // have to call stackalloc on scheduler stack.
1135 g->param = (void*)(StackSystem + stacksize); 1147 g->param = (void*)(StackSystem + stacksize);
1136 runtime·mcall(mstackalloc); 1148 runtime·mcall(mstackalloc);
1137 stk = g->param; 1149 stk = g->param;
1138 g->param = nil; 1150 g->param = nil;
1139 } 1151 }
1140 newg->stack0 = stk; 1152 newg->stack0 = stk;
1141 newg->stackguard = stk + StackGuard; 1153 newg->stackguard = stk + StackGuard;
1142 newg->stackbase = stk + StackSystem + stacksize - sizeof(Stktop) ; 1154 newg->stackbase = stk + StackSystem + stacksize - sizeof(Stktop) ;
1143 runtime·memclr(newg->stackbase, sizeof(Stktop)); 1155 runtime·memclr(newg->stackbase, sizeof(Stktop));
1144 } 1156 }
1145 return newg; 1157 return newg;
1146 } 1158 }
1147 1159
1148 /* 1160 // Create a new g running fn with siz bytes of arguments.
1149 * Newproc and deferproc need to be textflag 7 1161 // Put it on the queue of g's waiting to run.
1150 * (no possible stack split when nearing overflow) 1162 // The compiler turns a go statement into a call to this.
1151 * because they assume that the arguments to fn 1163 // Cannot split the stack because it assumes that the arguments
1152 * are available sequentially beginning at &arg0. 1164 // are available sequentially after &fn; they would not be
1153 * If a stack split happened, only the one word 1165 // copied if a stack split occurred. It's OK for this to call
1154 * arg0 would be copied. It's okay if any functions 1166 // functions that split the stack.
1155 * they call split the stack below the newproc frame.
1156 */
1157 #pragma textflag 7 1167 #pragma textflag 7
1158 void 1168 void
1159 runtime·newproc(int32 siz, byte* fn, ...) 1169 runtime·newproc(int32 siz, byte* fn, ...)
1160 { 1170 {
1161 byte *argp; 1171 byte *argp;
1162 1172
1163 if(thechar == '5') 1173 if(thechar == '5')
1164 argp = (byte*)(&fn+2); // skip caller's saved LR 1174 argp = (byte*)(&fn+2); // skip caller's saved LR
1165 else 1175 else
1166 argp = (byte*)(&fn+1); 1176 argp = (byte*)(&fn+1);
1167 runtime·newproc1(fn, argp, siz, 0, runtime·getcallerpc(&siz)); 1177 runtime·newproc1(fn, argp, siz, 0, runtime·getcallerpc(&siz));
1168 } 1178 }
1169 1179
1180 // Create a new g running fn with narg bytes of arguments starting
1181 // at argp and returning nret bytes of results. callerpc is the
1182 // address of the go statement that created this. The new g is put
1183 // on the queue of g's waiting to run.
1170 G* 1184 G*
1171 runtime·newproc1(byte *fn, byte *argp, int32 narg, int32 nret, void *callerpc) 1185 runtime·newproc1(byte *fn, byte *argp, int32 narg, int32 nret, void *callerpc)
1172 { 1186 {
1173 byte *sp; 1187 byte *sp;
1174 G *newg; 1188 G *newg;
1175 int32 siz; 1189 int32 siz;
1176 1190
1177 //printf("newproc1 %p %p narg=%d nret=%d\n", fn, argp, narg, nret); 1191 //printf("newproc1 %p %p narg=%d nret=%d\n", fn, argp, narg, nret);
1178 siz = narg + nret; 1192 siz = narg + nret;
1179 siz = (siz+7) & ~7; 1193 siz = (siz+7) & ~7;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 runtime·sched.goidgen++; 1234 runtime·sched.goidgen++;
1221 newg->goid = runtime·sched.goidgen; 1235 newg->goid = runtime·sched.goidgen;
1222 1236
1223 newprocreadylocked(newg); 1237 newprocreadylocked(newg);
1224 schedunlock(); 1238 schedunlock();
1225 1239
1226 return newg; 1240 return newg;
1227 //printf(" goid=%d\n", newg->goid); 1241 //printf(" goid=%d\n", newg->goid);
1228 } 1242 }
1229 1243
1244 // Create a new deferred function fn with siz bytes of arguments.
1245 // The compiler turns a defer statement into a call to this.
1246 // Cannot split the stack because it assumes that the arguments
1247 // are available sequentially after &fn; they would not be
1248 // copied if a stack split occurred. It's OK for this to call
1249 // functions that split the stack.
1230 #pragma textflag 7 1250 #pragma textflag 7
1231 uintptr 1251 uintptr
1232 runtime·deferproc(int32 siz, byte* fn, ...) 1252 runtime·deferproc(int32 siz, byte* fn, ...)
1233 { 1253 {
1234 Defer *d; 1254 Defer *d;
1235 1255
1236 d = runtime·malloc(sizeof(*d) + siz - sizeof(d->args)); 1256 d = runtime·malloc(sizeof(*d) + siz - sizeof(d->args));
1237 d->fn = fn; 1257 d->fn = fn;
1238 d->siz = siz; 1258 d->siz = siz;
1239 d->pc = runtime·getcallerpc(&siz); 1259 d->pc = runtime·getcallerpc(&siz);
1240 if(thechar == '5') 1260 if(thechar == '5')
1241 d->argp = (byte*)(&fn+2); // skip caller's saved link register 1261 d->argp = (byte*)(&fn+2); // skip caller's saved link register
1242 else 1262 else
1243 d->argp = (byte*)(&fn+1); 1263 d->argp = (byte*)(&fn+1);
1244 runtime·memmove(d->args, d->argp, d->siz); 1264 runtime·memmove(d->args, d->argp, d->siz);
1245 1265
1246 d->link = g->defer; 1266 d->link = g->defer;
1247 g->defer = d; 1267 g->defer = d;
1248 1268
1249 // deferproc returns 0 normally. 1269 // deferproc returns 0 normally.
1250 // a deferred func that stops a panic 1270 // a deferred func that stops a panic
1251 // makes the deferproc return 1. 1271 // makes the deferproc return 1.
1252 // the code the compiler generates always 1272 // the code the compiler generates always
1253 // checks the return value and jumps to the 1273 // checks the return value and jumps to the
1254 // end of the function if deferproc returns != 0. 1274 // end of the function if deferproc returns != 0.
1255 return 0; 1275 return 0;
1256 } 1276 }
1257 1277
1278 // Run a deferred function if there is one.
1279 // The compiler inserts a call to this at the end of any
1280 // function which calls defer.
1281 // If there is a deferred function, this will call runtime·jmpdefer,
1282 // which will jump to the deferred function such that it appears
1283 // to have been called by the caller of deferreturn at the point
1284 // just before deferreturn was called. The effect is that deferreturn
1285 // is called again and again until there are no more deferred functions.
1286 // Cannot split the stack because we reuse the caller's frame to
1287 // call the deferred function.
1258 #pragma textflag 7 1288 #pragma textflag 7
1259 void 1289 void
1260 runtime·deferreturn(uintptr arg0) 1290 runtime·deferreturn(uintptr arg0)
1261 { 1291 {
1262 Defer *d; 1292 Defer *d;
1263 byte *argp, *fn; 1293 byte *argp, *fn;
1264 1294
1265 d = g->defer; 1295 d = g->defer;
1266 if(d == nil) 1296 if(d == nil)
1267 return; 1297 return;
1268 argp = (byte*)&arg0; 1298 argp = (byte*)&arg0;
1269 if(d->argp != argp) 1299 if(d->argp != argp)
1270 return; 1300 return;
1271 runtime·memmove(argp, d->args, d->siz); 1301 runtime·memmove(argp, d->args, d->siz);
1272 g->defer = d->link; 1302 g->defer = d->link;
1273 fn = d->fn; 1303 fn = d->fn;
1274 if(!d->nofree) 1304 if(!d->nofree)
1275 runtime·free(d); 1305 runtime·free(d);
1276 runtime·jmpdefer(fn, argp); 1306 runtime·jmpdefer(fn, argp);
1277 } 1307 }
1278 1308
1309 // Run all deferred functions for the current goroutine.
1279 static void 1310 static void
1280 rundefer(void) 1311 rundefer(void)
1281 { 1312 {
1282 Defer *d; 1313 Defer *d;
1283 1314
1284 while((d = g->defer) != nil) { 1315 while((d = g->defer) != nil) {
1285 g->defer = d->link; 1316 g->defer = d->link;
1286 reflect·call(d->fn, d->args, d->siz); 1317 reflect·call(d->fn, d->args, d->siz);
1287 if(!d->nofree) 1318 if(!d->nofree)
1288 runtime·free(d); 1319 runtime·free(d);
(...skipping 21 matching lines...) Expand all
1310 if(top->free != 0) 1341 if(top->free != 0)
1311 runtime·stackfree(stk, top->free); 1342 runtime·stackfree(stk, top->free);
1312 } 1343 }
1313 1344
1314 if(sp != nil && (sp < gp->stackguard - StackGuard || gp->stackbase < sp) ) { 1345 if(sp != nil && (sp < gp->stackguard - StackGuard || gp->stackbase < sp) ) {
1315 runtime·printf("recover: %p not in [%p, %p]\n", sp, gp->stackgua rd - StackGuard, gp->stackbase); 1346 runtime·printf("recover: %p not in [%p, %p]\n", sp, gp->stackgua rd - StackGuard, gp->stackbase);
1316 runtime·throw("bad unwindstack"); 1347 runtime·throw("bad unwindstack");
1317 } 1348 }
1318 } 1349 }
1319 1350
1351 // Print all currently active panics. Used when crashing.
1320 static void 1352 static void
1321 printpanics(Panic *p) 1353 printpanics(Panic *p)
1322 { 1354 {
1323 if(p->link) { 1355 if(p->link) {
1324 printpanics(p->link); 1356 printpanics(p->link);
1325 runtime·printf("\t"); 1357 runtime·printf("\t");
1326 } 1358 }
1327 runtime·printf("panic: "); 1359 runtime·printf("panic: ");
1328 runtime·printany(p->arg); 1360 runtime·printany(p->arg);
1329 if(p->recovered) 1361 if(p->recovered)
1330 runtime·printf(" [recovered]"); 1362 runtime·printf(" [recovered]");
1331 runtime·printf("\n"); 1363 runtime·printf("\n");
1332 } 1364 }
1333 1365
1334 static void recovery(G*); 1366 static void recovery(G*);
1335 1367
1368 // The implementation of the predeclared function panic.
1336 void 1369 void
1337 runtime·panic(Eface e) 1370 runtime·panic(Eface e)
1338 { 1371 {
1339 Defer *d; 1372 Defer *d;
1340 Panic *p; 1373 Panic *p;
1341 1374
1342 p = runtime·mal(sizeof *p); 1375 p = runtime·mal(sizeof *p);
1343 p->arg = e; 1376 p->arg = e;
1344 p->link = g->panic; 1377 p->link = g->panic;
1345 p->stackbase = g->stackbase; 1378 p->stackbase = g->stackbase;
(...skipping 22 matching lines...) Expand all
1368 if(!d->nofree) 1401 if(!d->nofree)
1369 runtime·free(d); 1402 runtime·free(d);
1370 } 1403 }
1371 1404
1372 // ran out of deferred calls - old-school panic now 1405 // ran out of deferred calls - old-school panic now
1373 runtime·startpanic(); 1406 runtime·startpanic();
1374 printpanics(g->panic); 1407 printpanics(g->panic);
1375 runtime·dopanic(0); 1408 runtime·dopanic(0);
1376 } 1409 }
1377 1410
1411 // Unwind the stack after a deferred function calls recover
1412 // after a panic. Then arrange to continue running as though
1413 // the caller of the deferred function returned normally.
1378 static void 1414 static void
1379 recovery(G *gp) 1415 recovery(G *gp)
1380 { 1416 {
1381 Defer *d; 1417 Defer *d;
1382 1418
1383 // Rewind gp's stack; we're running on m->g0's stack. 1419 // Rewind gp's stack; we're running on m->g0's stack.
1384 d = gp->defer; 1420 d = gp->defer;
1385 gp->defer = d->link; 1421 gp->defer = d->link;
1386 1422
1387 // Unwind to the stack frame with d's arguments in it. 1423 // Unwind to the stack frame with d's arguments in it.
(...skipping 11 matching lines...) Expand all
1399 if(thechar == '5') 1435 if(thechar == '5')
1400 gp->sched.sp = (byte*)d->argp - 4*sizeof(uintptr); 1436 gp->sched.sp = (byte*)d->argp - 4*sizeof(uintptr);
1401 else 1437 else
1402 gp->sched.sp = (byte*)d->argp - 2*sizeof(uintptr); 1438 gp->sched.sp = (byte*)d->argp - 2*sizeof(uintptr);
1403 gp->sched.pc = d->pc; 1439 gp->sched.pc = d->pc;
1404 if(!d->nofree) 1440 if(!d->nofree)
1405 runtime·free(d); 1441 runtime·free(d);
1406 runtime·gogo(&gp->sched, 1); 1442 runtime·gogo(&gp->sched, 1);
1407 } 1443 }
1408 1444
1409 #pragma textflag 7» /* no split, or else g->stackguard is not the stack for fp */ 1445 // The implementation of the predeclared function recover.
1446 // Cannot split the stack because it needs to reliably
1447 // find the stack segment of its caller.
1448 #pragma textflag 7
1410 void 1449 void
1411 runtime·recover(byte *argp, Eface ret) 1450 runtime·recover(byte *argp, Eface ret)
1412 { 1451 {
1413 Stktop *top, *oldtop; 1452 Stktop *top, *oldtop;
1414 Panic *p; 1453 Panic *p;
1415 1454
1416 // Must be a panic going on. 1455 // Must be a panic going on.
1417 if((p = g->panic) == nil || p->recovered) 1456 if((p = g->panic) == nil || p->recovered)
1418 goto nomatch; 1457 goto nomatch;
1419 1458
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 rundefer(); 1550 rundefer();
1512 runtime·goexit(); 1551 runtime·goexit();
1513 } 1552 }
1514 1553
1515 void 1554 void
1516 runtime·Gosched(void) 1555 runtime·Gosched(void)
1517 { 1556 {
1518 runtime·gosched(); 1557 runtime·gosched();
1519 } 1558 }
1520 1559
1560 // Implementation of runtime.GOMAXPROCS.
1521 // delete when scheduler is stronger 1561 // delete when scheduler is stronger
1522 int32 1562 int32
1523 runtime·gomaxprocsfunc(int32 n) 1563 runtime·gomaxprocsfunc(int32 n)
1524 { 1564 {
1525 int32 ret; 1565 int32 ret;
1526 uint32 v; 1566 uint32 v;
1527 1567
1528 schedlock(); 1568 schedlock();
1529 ret = runtime·gomaxprocs; 1569 ret = runtime·gomaxprocs;
1530 if(n <= 0) 1570 if(n <= 0)
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1626 runtime·throw("runtime: mcall function returned"); 1666 runtime·throw("runtime: mcall function returned");
1627 } 1667 }
1628 1668
1629 static struct { 1669 static struct {
1630 Lock; 1670 Lock;
1631 void (*fn)(uintptr*, int32); 1671 void (*fn)(uintptr*, int32);
1632 int32 hz; 1672 int32 hz;
1633 uintptr pcbuf[100]; 1673 uintptr pcbuf[100];
1634 } prof; 1674 } prof;
1635 1675
1676 // Called if we receive a SIGPROF signal.
1636 void 1677 void
1637 runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp) 1678 runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp)
1638 { 1679 {
1639 int32 n; 1680 int32 n;
1640 1681
1641 if(prof.fn == nil || prof.hz == 0) 1682 if(prof.fn == nil || prof.hz == 0)
1642 return; 1683 return;
1643 1684
1644 runtime·lock(&prof); 1685 runtime·lock(&prof);
1645 if(prof.fn == nil) { 1686 if(prof.fn == nil) {
1646 runtime·unlock(&prof); 1687 runtime·unlock(&prof);
1647 return; 1688 return;
1648 } 1689 }
1649 n = runtime·gentraceback(pc, sp, lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf )); 1690 n = runtime·gentraceback(pc, sp, lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf ));
1650 if(n > 0) 1691 if(n > 0)
1651 prof.fn(prof.pcbuf, n); 1692 prof.fn(prof.pcbuf, n);
1652 runtime·unlock(&prof); 1693 runtime·unlock(&prof);
1653 } 1694 }
1654 1695
1696 // Arrange to call fn with a traceback hz times a second.
1655 void 1697 void
1656 runtime·setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz) 1698 runtime·setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz)
1657 { 1699 {
1658 // Force sane arguments. 1700 // Force sane arguments.
1659 if(hz < 0) 1701 if(hz < 0)
1660 hz = 0; 1702 hz = 0;
1661 if(hz == 0) 1703 if(hz == 0)
1662 fn = nil; 1704 fn = nil;
1663 if(fn == nil) 1705 if(fn == nil)
1664 hz = 0; 1706 hz = 0;
(...skipping 10 matching lines...) Expand all
1675 runtime·lock(&runtime·sched); 1717 runtime·lock(&runtime·sched);
1676 runtime·sched.profilehz = hz; 1718 runtime·sched.profilehz = hz;
1677 runtime·unlock(&runtime·sched); 1719 runtime·unlock(&runtime·sched);
1678 1720
1679 if(hz != 0) 1721 if(hz != 0)
1680 runtime·resetcpuprofiler(hz); 1722 runtime·resetcpuprofiler(hz);
1681 } 1723 }
1682 1724
1683 void (*libcgo_setenv)(byte**); 1725 void (*libcgo_setenv)(byte**);
1684 1726
1727 // Update the C environment if cgo is loaded.
1728 // Called from os.Setenv.
1685 void 1729 void
1686 os·setenv_c(String k, String v) 1730 os·setenv_c(String k, String v)
1687 { 1731 {
1688 byte *arg[2]; 1732 byte *arg[2];
1689 1733
1690 if(libcgo_setenv == nil) 1734 if(libcgo_setenv == nil)
1691 return; 1735 return;
1692 1736
1693 arg[0] = runtime·malloc(k.len + 1); 1737 arg[0] = runtime·malloc(k.len + 1);
1694 runtime·memmove(arg[0], k.str, k.len); 1738 runtime·memmove(arg[0], k.str, k.len);
1695 arg[0][k.len] = 0; 1739 arg[0][k.len] = 0;
1696 1740
1697 arg[1] = runtime·malloc(v.len + 1); 1741 arg[1] = runtime·malloc(v.len + 1);
1698 runtime·memmove(arg[1], v.str, v.len); 1742 runtime·memmove(arg[1], v.str, v.len);
1699 arg[1][v.len] = 0; 1743 arg[1][v.len] = 0;
1700 1744
1701 runtime·asmcgocall((void*)libcgo_setenv, arg); 1745 runtime·asmcgocall((void*)libcgo_setenv, arg);
1702 runtime·free(arg[0]); 1746 runtime·free(arg[0]);
1703 runtime·free(arg[1]); 1747 runtime·free(arg[1]);
1704 } 1748 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b