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

Side by Side Diff: src/pkg/runtime/proc.c

Issue 5334051: code review 5334051: runtime: add timer support, use for package time (Closed)
Patch Set: diff -r c8c9ccd19020 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:
View unified diff | Download patch
OLDNEW
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"
11 11
12 bool runtime·iscgo; 12 bool runtime·iscgo;
13 13
14 static void unwindstack(G*, byte*); 14 static void unwindstack(G*, byte*);
15 static void schedule(G*); 15 static void schedule(G*);
16 static void acquireproc(void); 16 static void acquireproc(void);
17 static void releaseproc(void); 17 static void releaseproc(void);
18 static M *startm(void);
19 18
20 typedef struct Sched Sched; 19 typedef struct Sched Sched;
21 20
22 M runtime·m0; 21 M runtime·m0;
23 G runtime·g0; // idle goroutine for m0 22 G runtime·g0; // idle goroutine for m0
24 23
25 static int32 debug = 0; 24 static int32 debug = 0;
26 25
27 int32 runtime·gcwaiting; 26 int32 runtime·gcwaiting;
28 27
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 // g queue or changing mcpumax. Entersyscall can decrement 576 // g queue or changing mcpumax. Entersyscall can decrement
578 // mcpu, but if does so when there is something on the g queue, 577 // mcpu, but if does so when there is something on the g queue,
579 // the gwait bit will be set, so entersyscall will take the slow path 578 // the gwait bit will be set, so entersyscall will take the slow path
580 // and use the sched lock. So it cannot invalidate our decision . 579 // and use the sched lock. So it cannot invalidate our decision .
581 // 580 //
582 // Wait on global m queue. 581 // Wait on global m queue.
583 mput(m); 582 mput(m);
584 } 583 }
585 584
586 v = runtime·atomicload(&runtime·sched.atomic); 585 v = runtime·atomicload(&runtime·sched.atomic);
587 » if(runtime·sched.grunning == 0) 586 » if(runtime·sched.grunning == 0 && !runtime·havetimers())
dvyukov 2011/11/07 10:54:15 Need to re-check the condition in time.goc when ha
588 runtime·throw("all goroutines are asleep - deadlock!"); 587 runtime·throw("all goroutines are asleep - deadlock!");
589 m->nextg = nil; 588 m->nextg = nil;
590 m->waitnextg = 1; 589 m->waitnextg = 1;
591 runtime·noteclear(&m->havenextg); 590 runtime·noteclear(&m->havenextg);
592 591
593 // Stoptheworld is waiting for all but its cpu to go to stop. 592 // Stoptheworld is waiting for all but its cpu to go to stop.
594 // Entersyscall might have decremented mcpu too, but if so 593 // Entersyscall might have decremented mcpu too, but if so
595 // it will see the waitstop and take the slow path. 594 // it will see the waitstop and take the slow path.
596 // Exitsyscall never increments mcpu beyond mcpumax. 595 // Exitsyscall never increments mcpu beyond mcpumax.
597 if(atomic_waitstop(v) && atomic_mcpu(v) <= atomic_mcpumax(v)) { 596 if(atomic_waitstop(v) && atomic_mcpu(v) <= atomic_mcpumax(v)) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 if(extra && canaddmcpu()) { 693 if(extra && canaddmcpu()) {
695 // Start a new m that will (we hope) be idle 694 // Start a new m that will (we hope) be idle
696 // and so available to help when the next 695 // and so available to help when the next
697 // garbage collection happens. 696 // garbage collection happens.
698 // canaddmcpu above did mcpu++ 697 // canaddmcpu above did mcpu++
699 // (necessary, because m will be doing various 698 // (necessary, because m will be doing various
700 // initialization work so is definitely running), 699 // initialization work so is definitely running),
701 // but m is not running a specific goroutine, 700 // but m is not running a specific goroutine,
702 // so set the helpgc flag as a signal to m's 701 // so set the helpgc flag as a signal to m's
703 // first schedule(nil) to mcpu-- and grunning--. 702 // first schedule(nil) to mcpu-- and grunning--.
704 » » m = startm(); 703 » » m = runtime·newm(nil);
705 m->helpgc = 1; 704 m->helpgc = 1;
706 runtime·sched.grunning++; 705 runtime·sched.grunning++;
707 } 706 }
708 schedunlock(); 707 schedunlock();
709 } 708 }
710 709
711 // Called to start an M. 710 // Called to start an M.
712 void 711 void
713 runtime·mstart(void) 712 runtime·mstart(void)
714 { 713 {
715 if(g != m->g0) 714 if(g != m->g0)
716 runtime·throw("bad runtime·mstart"); 715 runtime·throw("bad runtime·mstart");
717 716
718 // Record top of stack for use by mcall. 717 // Record top of stack for use by mcall.
719 // Once we call schedule we're never coming back, 718 // Once we call schedule we're never coming back,
720 // so other calls can reuse this stack space. 719 // so other calls can reuse this stack space.
721 runtime·gosave(&m->g0->sched); 720 runtime·gosave(&m->g0->sched);
722 m->g0->sched.pc = (void*)-1; // make sure it is never used 721 m->g0->sched.pc = (void*)-1; // make sure it is never used
723 722
724 runtime·minit(); 723 runtime·minit();
724 if(m->procfn)
725 m->procfn();
dvyukov 2011/11/07 10:35:02 I think as of now it will throw if fall through to
725 schedule(nil); 726 schedule(nil);
726 } 727 }
727 728
728 // When running with cgo, we call libcgo_thread_start 729 // When running with cgo, we call libcgo_thread_start
729 // to start threads for us so that we can play nicely with 730 // to start threads for us so that we can play nicely with
730 // foreign code. 731 // foreign code.
731 void (*libcgo_thread_start)(void*); 732 void (*libcgo_thread_start)(void*);
732 733
733 typedef struct CgoThreadStart CgoThreadStart; 734 typedef struct CgoThreadStart CgoThreadStart;
734 struct CgoThreadStart 735 struct CgoThreadStart
(...skipping 16 matching lines...) Expand all
751 if(m->mallocing || m->gcing) 752 if(m->mallocing || m->gcing)
752 return; 753 return;
753 754
754 while(haveg() && canaddmcpu()) { 755 while(haveg() && canaddmcpu()) {
755 gp = gget(); 756 gp = gget();
756 if(gp == nil) 757 if(gp == nil)
757 runtime·throw("gget inconsistency"); 758 runtime·throw("gget inconsistency");
758 759
759 // Find the m that will run gp. 760 // Find the m that will run gp.
760 if((mp = mget(gp)) == nil) 761 if((mp = mget(gp)) == nil)
761 » » » mp = startm(); 762 » » » mp = runtime·newm(nil);
762 mnextg(mp, gp); 763 mnextg(mp, gp);
763 } 764 }
764 } 765 }
765 766
766 static M* 767 M*
767 startm(void) 768 runtime·newm(void (*procfn)(void))
768 { 769 {
769 M *m; 770 M *m;
770 771
771 m = runtime·malloc(sizeof(M)); 772 m = runtime·malloc(sizeof(M));
772 mcommoninit(m); 773 mcommoninit(m);
774 m->procfn = procfn;
dvyukov 2011/11/07 10:35:02 It is quite fragile. See newm comment in time.goc.
773 775
774 if(runtime·iscgo) { 776 if(runtime·iscgo) {
775 CgoThreadStart ts; 777 CgoThreadStart ts;
776 778
777 if(libcgo_thread_start == nil) 779 if(libcgo_thread_start == nil)
778 runtime·throw("libcgo_thread_start missing"); 780 runtime·throw("libcgo_thread_start missing");
779 // pthread_create will make us a stack. 781 // pthread_create will make us a stack.
780 m->g0 = runtime·malg(-1); 782 m->g0 = runtime·malg(-1);
781 ts.m = m; 783 ts.m = m;
782 ts.g = m->g0; 784 ts.g = m->g0;
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 arg[0][k.len] = 0; 1690 arg[0][k.len] = 0;
1689 1691
1690 arg[1] = runtime·malloc(v.len + 1); 1692 arg[1] = runtime·malloc(v.len + 1);
1691 runtime·memmove(arg[1], v.str, v.len); 1693 runtime·memmove(arg[1], v.str, v.len);
1692 arg[1][v.len] = 0; 1694 arg[1][v.len] = 0;
1693 1695
1694 runtime·asmcgocall((void*)libcgo_setenv, arg); 1696 runtime·asmcgocall((void*)libcgo_setenv, arg);
1695 runtime·free(arg[0]); 1697 runtime·free(arg[0]);
1696 runtime·free(arg[1]); 1698 runtime·free(arg[1]);
1697 } 1699 }
OLDNEW

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