LEFT | RIGHT |
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 "defs_GOOS_GOARCH.h" | 7 #include "defs_GOOS_GOARCH.h" |
8 #include "malloc.h" | 8 #include "malloc.h" |
9 #include "os_GOOS.h" | 9 #include "os_GOOS.h" |
10 #include "stack.h" | 10 #include "stack.h" |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 for(;;) { | 157 for(;;) { |
158 v = runtime·sched.atomic; | 158 v = runtime·sched.atomic; |
159 w = v; | 159 w = v; |
160 w &= ~(mcpuMask<<mcpumaxShift); | 160 w &= ~(mcpuMask<<mcpumaxShift); |
161 w |= n<<mcpumaxShift; | 161 w |= n<<mcpumaxShift; |
162 if(runtime·cas(&runtime·sched.atomic, v, w)) | 162 if(runtime·cas(&runtime·sched.atomic, v, w)) |
163 break; | 163 break; |
164 } | 164 } |
165 } | 165 } |
166 | 166 |
| 167 // Keep trace of scavenger's goroutine for deadlock detection. |
| 168 static G *scvg; |
| 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 calls runtime·main. | 177 // The new G calls runtime·main. |
175 void | 178 void |
176 runtime·schedinit(void) | 179 runtime·schedinit(void) |
(...skipping 23 matching lines...) Expand all Loading... |
200 setmcpumax(runtime·gomaxprocs); | 203 setmcpumax(runtime·gomaxprocs); |
201 runtime·singleproc = runtime·gomaxprocs == 1; | 204 runtime·singleproc = runtime·gomaxprocs == 1; |
202 | 205 |
203 canaddmcpu(); // mcpu++ to account for bootstrap m | 206 canaddmcpu(); // mcpu++ to account for bootstrap m |
204 m->helpgc = 1; // flag to tell schedule() to mcpu-- | 207 m->helpgc = 1; // flag to tell schedule() to mcpu-- |
205 runtime·sched.grunning++; | 208 runtime·sched.grunning++; |
206 | 209 |
207 mstats.enablegc = 1; | 210 mstats.enablegc = 1; |
208 m->nomemprof--; | 211 m->nomemprof--; |
209 | 212 |
210 » runtime·newproc1((byte*)runtime·MHeap_Scavenger, nil, 0, 0, runtime·sche
dinit); | 213 » scvg = runtime·newproc1((byte*)runtime·MHeap_Scavenger, nil, 0, 0, runti
me·schedinit); |
211 } | 214 } |
212 | 215 |
213 extern void main·init(void); | 216 extern void main·init(void); |
214 extern void main·main(void); | 217 extern void main·main(void); |
215 | 218 |
216 // The main goroutine. | 219 // The main goroutine. |
217 void | 220 void |
218 runtime·main(void) | 221 runtime·main(void) |
219 { | 222 { |
220 // Lock the main goroutine onto this, the main OS thread, | 223 // Lock the main goroutine onto this, the main OS thread, |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 mcommoninit(M *m) | 330 mcommoninit(M *m) |
328 { | 331 { |
329 // Add to runtime·allm so garbage collector doesn't free m | 332 // Add to runtime·allm so garbage collector doesn't free m |
330 // when it is just in a register or thread-local storage. | 333 // when it is just in a register or thread-local storage. |
331 m->alllink = runtime·allm; | 334 m->alllink = runtime·allm; |
332 // runtime·Cgocalls() iterates over allm w/o schedlock, | 335 // runtime·Cgocalls() iterates over allm w/o schedlock, |
333 // so we need to publish it safely. | 336 // so we need to publish it safely. |
334 runtime·atomicstorep(&runtime·allm, m); | 337 runtime·atomicstorep(&runtime·allm, m); |
335 | 338 |
336 m->id = runtime·sched.mcount++; | 339 m->id = runtime·sched.mcount++; |
337 » m->fastrand = 0x49f6428aUL + m->id; | 340 » m->fastrand = 0x49f6428aUL + m->id + runtime·cputicks(); |
338 m->stackalloc = runtime·malloc(sizeof(*m->stackalloc)); | 341 m->stackalloc = runtime·malloc(sizeof(*m->stackalloc)); |
339 runtime·FixAlloc_Init(m->stackalloc, FixedStack, runtime·SysAlloc, nil,
nil); | 342 runtime·FixAlloc_Init(m->stackalloc, FixedStack, runtime·SysAlloc, nil,
nil); |
340 | 343 |
341 if(m->mcache == nil) | 344 if(m->mcache == nil) |
342 m->mcache = runtime·allocmcache(); | 345 m->mcache = runtime·allocmcache(); |
343 } | 346 } |
344 | 347 |
345 // Try to increment mcpu. Report whether succeeded. | 348 // Try to increment mcpu. Report whether succeeded. |
346 static bool | 349 static bool |
347 canaddmcpu(void) | 350 canaddmcpu(void) |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 // We hold the sched lock, so no one else is manipulating the | 578 // We hold the sched lock, so no one else is manipulating the |
576 // g queue or changing mcpumax. Entersyscall can decrement | 579 // g queue or changing mcpumax. Entersyscall can decrement |
577 // mcpu, but if does so when there is something on the g queue, | 580 // mcpu, but if does so when there is something on the g queue, |
578 // the gwait bit will be set, so entersyscall will take the slow
path | 581 // the gwait bit will be set, so entersyscall will take the slow
path |
579 // and use the sched lock. So it cannot invalidate our decision
. | 582 // and use the sched lock. So it cannot invalidate our decision
. |
580 // | 583 // |
581 // Wait on global m queue. | 584 // Wait on global m queue. |
582 mput(m); | 585 mput(m); |
583 } | 586 } |
584 | 587 |
585 » v = runtime·atomicload(&runtime·sched.atomic); | 588 » // Look for deadlock situation: one single active g which happens to be
scvg. |
586 » if(runtime·sched.grunning == 1 && runtime·sched.gwait == 0) | 589 » if(runtime·sched.grunning == 1 && runtime·sched.gwait == 0) { |
587 » » runtime·throw("all goroutines are asleep - deadlock!"); | 590 » » if(scvg->status == Grunning || scvg->status == Gsyscall) |
| 591 » » » runtime·throw("all goroutines are asleep - deadlock!"); |
| 592 » } |
| 593 |
588 m->nextg = nil; | 594 m->nextg = nil; |
589 m->waitnextg = 1; | 595 m->waitnextg = 1; |
590 runtime·noteclear(&m->havenextg); | 596 runtime·noteclear(&m->havenextg); |
591 | 597 |
592 // Stoptheworld is waiting for all but its cpu to go to stop. | 598 // Stoptheworld is waiting for all but its cpu to go to stop. |
593 // Entersyscall might have decremented mcpu too, but if so | 599 // Entersyscall might have decremented mcpu too, but if so |
594 // it will see the waitstop and take the slow path. | 600 // it will see the waitstop and take the slow path. |
595 // Exitsyscall never increments mcpu beyond mcpumax. | 601 // Exitsyscall never increments mcpu beyond mcpumax. |
| 602 v = runtime·atomicload(&runtime·sched.atomic); |
596 if(atomic_waitstop(v) && atomic_mcpu(v) <= atomic_mcpumax(v)) { | 603 if(atomic_waitstop(v) && atomic_mcpu(v) <= atomic_mcpumax(v)) { |
597 // set waitstop = 0 (known to be 1) | 604 // set waitstop = 0 (known to be 1) |
598 runtime·xadd(&runtime·sched.atomic, -1<<waitstopShift); | 605 runtime·xadd(&runtime·sched.atomic, -1<<waitstopShift); |
599 runtime·notewakeup(&runtime·sched.stopped); | 606 runtime·notewakeup(&runtime·sched.stopped); |
600 } | 607 } |
601 schedunlock(); | 608 schedunlock(); |
602 | 609 |
603 runtime·notesleep(&m->havenextg); | 610 runtime·notesleep(&m->havenextg); |
604 if(m->helpgc) { | 611 if(m->helpgc) { |
605 runtime·gchelper(); | 612 runtime·gchelper(); |
(...skipping 1133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1739 arg[0][k.len] = 0; | 1746 arg[0][k.len] = 0; |
1740 | 1747 |
1741 arg[1] = runtime·malloc(v.len + 1); | 1748 arg[1] = runtime·malloc(v.len + 1); |
1742 runtime·memmove(arg[1], v.str, v.len); | 1749 runtime·memmove(arg[1], v.str, v.len); |
1743 arg[1][v.len] = 0; | 1750 arg[1][v.len] = 0; |
1744 | 1751 |
1745 runtime·asmcgocall((void*)libcgo_setenv, arg); | 1752 runtime·asmcgocall((void*)libcgo_setenv, arg); |
1746 runtime·free(arg[0]); | 1753 runtime·free(arg[0]); |
1747 runtime·free(arg[1]); | 1754 runtime·free(arg[1]); |
1748 } | 1755 } |
LEFT | RIGHT |