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 "zaexperiment.h" | 7 #include "zaexperiment.h" |
8 #include "malloc.h" | 8 #include "malloc.h" |
9 #include "stack.h" | 9 #include "stack.h" |
10 #include "race.h" | 10 #include "race.h" |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 void | 127 void |
128 runtime·schedinit(void) | 128 runtime·schedinit(void) |
129 { | 129 { |
130 int32 n, procs; | 130 int32 n, procs; |
131 byte *p; | 131 byte *p; |
132 Eface i; | 132 Eface i; |
133 | 133 |
134 runtime·sched.maxmcount = 10000; | 134 runtime·sched.maxmcount = 10000; |
135 runtime·precisestack = haveexperiment("precisestack"); | 135 runtime·precisestack = haveexperiment("precisestack"); |
136 | 136 |
137 runtime·mprofinit(); | |
138 runtime·mallocinit(); | 137 runtime·mallocinit(); |
139 mcommoninit(m); | 138 mcommoninit(m); |
140 ········ | 139 ········ |
141 // Initialize the itable value for newErrorCString, | 140 // Initialize the itable value for newErrorCString, |
142 // so that the next time it gets called, possibly | 141 // so that the next time it gets called, possibly |
143 // in a fault during a garbage collection, it will not | 142 // in a fault during a garbage collection, it will not |
144 // need to allocated memory. | 143 // need to allocated memory. |
145 runtime·newErrorCString(0, &i); | 144 runtime·newErrorCString(0, &i); |
146 | 145 |
147 runtime·goargs(); | 146 runtime·goargs(); |
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 m->nextp = nil; | 941 m->nextp = nil; |
943 } | 942 } |
944 | 943 |
945 static void | 944 static void |
946 mspinning(void) | 945 mspinning(void) |
947 { | 946 { |
948 m->spinning = true; | 947 m->spinning = true; |
949 } | 948 } |
950 | 949 |
951 // Schedules some M to run the p (creates an M if necessary). | 950 // Schedules some M to run the p (creates an M if necessary). |
952 // If p==nil, tries to get an idle P, if no idle P's returns false. | 951 // If p==nil, tries to get an idle P, if no idle P's does nothing. |
953 static void | 952 static void |
954 startm(P *p, bool spinning) | 953 startm(P *p, bool spinning) |
955 { | 954 { |
956 M *mp; | 955 M *mp; |
957 void (*fn)(void); | 956 void (*fn)(void); |
958 | 957 |
959 runtime·lock(&runtime·sched); | 958 runtime·lock(&runtime·sched); |
960 if(p == nil) { | 959 if(p == nil) { |
961 p = pidleget(); | 960 p = pidleget(); |
962 if(p == nil) { | 961 if(p == nil) { |
(...skipping 1826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2789 { | 2788 { |
2790 uint32 t, h, n, i; | 2789 uint32 t, h, n, i; |
2791 | 2790 |
2792 for(;;) { | 2791 for(;;) { |
2793 h = runtime·atomicload(&p->runqhead); // load-acquire, synchron
ize with other consumers | 2792 h = runtime·atomicload(&p->runqhead); // load-acquire, synchron
ize with other consumers |
2794 t = runtime·atomicload(&p->runqtail); // load-acquire, synchron
ize with the producer | 2793 t = runtime·atomicload(&p->runqtail); // load-acquire, synchron
ize with the producer |
2795 n = t-h; | 2794 n = t-h; |
2796 n = n - n/2; | 2795 n = n - n/2; |
2797 if(n == 0) | 2796 if(n == 0) |
2798 break; | 2797 break; |
| 2798 if(n > nelem(p->runq)/2) // read inconsistent h and t |
| 2799 continue; |
2799 for(i=0; i<n; i++) | 2800 for(i=0; i<n; i++) |
2800 batch[i] = p->runq[(h+i)%nelem(p->runq)]; | 2801 batch[i] = p->runq[(h+i)%nelem(p->runq)]; |
2801 if(runtime·cas(&p->runqhead, h, h+n)) // cas-release, commits c
onsume | 2802 if(runtime·cas(&p->runqhead, h, h+n)) // cas-release, commits c
onsume |
2802 break; | 2803 break; |
2803 } | 2804 } |
2804 return n; | 2805 return n; |
2805 } | 2806 } |
2806 | 2807 |
2807 // Steal half of elements from local runnable queue of p2 | 2808 // Steal half of elements from local runnable queue of p2 |
2808 // and put onto local runnable queue of p. | 2809 // and put onto local runnable queue of p. |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2935 if(experiment[i+j] != name[j]) | 2936 if(experiment[i+j] != name[j]) |
2936 goto nomatch; | 2937 goto nomatch; |
2937 if(experiment[i+j] != '\0' && experiment[i+j] != ',') | 2938 if(experiment[i+j] != '\0' && experiment[i+j] != ',') |
2938 goto nomatch; | 2939 goto nomatch; |
2939 return 1; | 2940 return 1; |
2940 } | 2941 } |
2941 nomatch:; | 2942 nomatch:; |
2942 } | 2943 } |
2943 return 0; | 2944 return 0; |
2944 } | 2945 } |
LEFT | RIGHT |