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

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

Issue 5309070: code review 5309070: runtime: lock the main goroutine to the main OS thread (Closed)
Left Patch Set: Created 13 years, 5 months ago
Right Patch Set: diff -r 738f105abf75 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:
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/runtime/debug.go ('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
(no file at all)
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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 int32 gcount; // number of g's that are alive 65 int32 gcount; // number of g's that are alive
66 int32 grunning; // number of g's running on cpu or in syscall 66 int32 grunning; // number of g's running on cpu or in syscall
67 67
68 M *mhead; // m's waiting for work 68 M *mhead; // m's waiting for work
69 int32 mwait; // number of m's waiting for work 69 int32 mwait; // number of m's waiting for work
70 int32 mcount; // number of m's that have been created 70 int32 mcount; // number of m's that have been created
71 71
72 volatile uint32 atomic; // atomic scheduling word (see below) 72 volatile uint32 atomic; // atomic scheduling word (see below)
73 73
74 int32 profilehz; // cpu profiling rate 74 int32 profilehz; // cpu profiling rate
75 ········
76 bool init; // running initialization
77 bool lockmain; // init called runtime.LockOSThread
75 78
76 Note stopped; // one g can set waitstop and wait here for m's to stop 79 Note stopped; // one g can set waitstop and wait here for m's to stop
77 }; 80 };
78 81
79 // The atomic word in sched is an atomic uint32 that 82 // The atomic word in sched is an atomic uint32 that
80 // holds these fields. 83 // holds these fields.
81 // 84 //
82 // [15 bits] mcpu number of m's executing on cpu 85 // [15 bits] mcpu number of m's executing on cpu
83 // [15 bits] mcpumax max number of m's allowed on cpu 86 // [15 bits] mcpumax max number of m's allowed on cpu
84 // [1 bit] waitstop some g is waiting on stopped 87 // [1 bit] waitstop some g is waiting on stopped
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 } 167 }
165 } 168 }
166 169
167 // The bootstrap sequence is: 170 // The bootstrap sequence is:
168 // 171 //
169 // call osinit 172 // call osinit
170 // call schedinit 173 // call schedinit
171 // make & queue new G 174 // make & queue new G
172 // call runtime·mstart 175 // call runtime·mstart
173 // 176 //
174 // The new G does: 177 // The new G calls runtime·main.
175 //
176 //» call main·init_function
177 //» call initdone
178 //» call main·main
179 void 178 void
180 runtime·schedinit(void) 179 runtime·schedinit(void)
181 { 180 {
182 int32 n; 181 int32 n;
183 byte *p; 182 byte *p;
184 183
185 m->nomemprof++; 184 m->nomemprof++;
186 runtime·mallocinit(); 185 runtime·mallocinit();
187 mcommoninit(m); 186 mcommoninit(m);
188 187
(...skipping 14 matching lines...) Expand all
203 } 202 }
204 setmcpumax(runtime·gomaxprocs); 203 setmcpumax(runtime·gomaxprocs);
205 runtime·singleproc = runtime·gomaxprocs == 1; 204 runtime·singleproc = runtime·gomaxprocs == 1;
206 205
207 canaddmcpu(); // mcpu++ to account for bootstrap m 206 canaddmcpu(); // mcpu++ to account for bootstrap m
208 m->helpgc = 1; // flag to tell schedule() to mcpu-- 207 m->helpgc = 1; // flag to tell schedule() to mcpu--
209 runtime·sched.grunning++; 208 runtime·sched.grunning++;
210 209
211 mstats.enablegc = 1; 210 mstats.enablegc = 1;
212 m->nomemprof--; 211 m->nomemprof--;
212 }
213
214 extern void main·init(void);
215 extern void main·main(void);
216
217 // The main goroutine.
218 void
219 runtime·main(void)
220 {
221 // Lock the main goroutine onto this, the main OS thread,
222 // during initialization. Most programs won't care, but a few
223 // do require certain calls to be made by the main thread.
224 // Those can arrange for main.main to run in the main thread
225 // by calling runtime.LockOSThread during initialization
226 // to preserve the lock.
227 runtime·LockOSThread();
228 runtime·sched.init = true;
229 main·init();
230 runtime·sched.init = false;
231 if(!runtime·sched.lockmain)
232 runtime·UnlockOSThread();
233
234 main·main();
235 runtime·exit(0);
236 for(;;)
237 *(int32*)runtime·main = 0;
213 } 238 }
214 239
215 // Lock the scheduler. 240 // Lock the scheduler.
216 static void 241 static void
217 schedlock(void) 242 schedlock(void)
218 { 243 {
219 runtime·lock(&runtime·sched); 244 runtime·lock(&runtime·sched);
220 } 245 }
221 246
222 // Unlock the scheduler. 247 // Unlock the scheduler.
(...skipping 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 rundefer(); 1512 rundefer();
1488 runtime·goexit(); 1513 runtime·goexit();
1489 } 1514 }
1490 1515
1491 void 1516 void
1492 runtime·Gosched(void) 1517 runtime·Gosched(void)
1493 { 1518 {
1494 runtime·gosched(); 1519 runtime·gosched();
1495 } 1520 }
1496 1521
1497 void
1498 runtime·LockOSThread(void)
1499 {
1500 m->lockedg = g;
1501 g->lockedm = m;
1502 }
1503
1504 // delete when scheduler is stronger 1522 // delete when scheduler is stronger
1505 int32 1523 int32
1506 runtime·gomaxprocsfunc(int32 n) 1524 runtime·gomaxprocsfunc(int32 n)
1507 { 1525 {
1508 int32 ret; 1526 int32 ret;
1509 uint32 v; 1527 uint32 v;
1510 1528
1511 schedlock(); 1529 schedlock();
1512 ret = runtime·gomaxprocs; 1530 ret = runtime·gomaxprocs;
1513 if(n <= 0) 1531 if(n <= 0)
(...skipping 20 matching lines...) Expand all
1534 runtime·gosched(); 1552 runtime·gosched();
1535 return ret; 1553 return ret;
1536 } 1554 }
1537 // handle more procs 1555 // handle more procs
1538 matchmg(); 1556 matchmg();
1539 schedunlock(); 1557 schedunlock();
1540 return ret; 1558 return ret;
1541 } 1559 }
1542 1560
1543 void 1561 void
1562 runtime·LockOSThread(void)
1563 {
1564 if(m == &runtime·m0 && runtime·sched.init) {
1565 runtime·sched.lockmain = true;
1566 return;
1567 }
1568 m->lockedg = g;
1569 g->lockedm = m;
1570 }
1571
1572 void
1544 runtime·UnlockOSThread(void) 1573 runtime·UnlockOSThread(void)
1545 { 1574 {
1575 if(m == &runtime·m0 && runtime·sched.init) {
1576 runtime·sched.lockmain = false;
1577 return;
1578 }
1546 m->lockedg = nil; 1579 m->lockedg = nil;
1547 g->lockedm = nil; 1580 g->lockedm = nil;
1548 } 1581 }
1549 1582
1550 bool 1583 bool
1551 runtime·lockedOSThread(void) 1584 runtime·lockedOSThread(void)
1552 { 1585 {
1553 return g->lockedm != nil && m->lockedg != nil; 1586 return g->lockedm != nil && m->lockedg != nil;
1554 } 1587 }
1555 1588
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 arg[0][k.len] = 0; 1688 arg[0][k.len] = 0;
1656 1689
1657 arg[1] = runtime·malloc(v.len + 1); 1690 arg[1] = runtime·malloc(v.len + 1);
1658 runtime·memmove(arg[1], v.str, v.len); 1691 runtime·memmove(arg[1], v.str, v.len);
1659 arg[1][v.len] = 0; 1692 arg[1][v.len] = 0;
1660 1693
1661 runtime·asmcgocall((void*)libcgo_setenv, arg); 1694 runtime·asmcgocall((void*)libcgo_setenv, arg);
1662 runtime·free(arg[0]); 1695 runtime·free(arg[0]);
1663 runtime·free(arg[1]); 1696 runtime·free(arg[1]);
1664 } 1697 }
LEFTRIGHT

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