LEFT | RIGHT |
(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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
LEFT | RIGHT |