all: remove 'extern register M *m' from runtime

The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).

This CL removes the extern register m; code now uses g->m.

On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.

The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:

BenchmarkBinaryTree17              5491374955     5471024381     -0.37%
BenchmarkFannkuch11                4357101311     4275174828     -1.88%
BenchmarkGobDecode                 11029957       11364184       +3.03%
BenchmarkGobEncode                 6852205        6784822        -0.98%
BenchmarkGzip                      650795967      650152275      -0.10%
BenchmarkGunzip                    140962363      141041670      +0.06%
BenchmarkHTTPClientServer          71581          73081          +2.10%
BenchmarkJSONEncode                31928079       31913356       -0.05%
BenchmarkJSONDecode                117470065      113689916      -3.22%
BenchmarkMandelbrot200             6008923        5998712        -0.17%
BenchmarkGoParse                   6310917        6327487        +0.26%
BenchmarkRegexpMatchMedium_1K      114568         114763         +0.17%
BenchmarkRegexpMatchHard_1K        168977         169244         +0.16%
BenchmarkRevcomp                   935294971      914060918      -2.27%
BenchmarkTemplate                  145917123      148186096      +1.55%

Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.

Actual code changes by Minux.
I only did the docs and the benchmarking.

LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
This commit is contained in:
Russ Cox 2014-06-26 11:54:39 -04:00
parent 2565b5c060
commit 89f185fe8a
98 changed files with 998 additions and 961 deletions

View file

@ -67,34 +67,34 @@ runtime·semasleep(int64 ns)
Timespec ts;
// spin-mutex lock
while(runtime·xchg(&m->waitsemalock, 1))
while(runtime·xchg(&g->m->waitsemalock, 1))
runtime·osyield();
for(;;) {
// lock held
if(m->waitsemacount == 0) {
if(g->m->waitsemacount == 0) {
// sleep until semaphore != 0 or timeout.
// thrsleep unlocks m->waitsemalock.
if(ns < 0)
runtime·thrsleep(&m->waitsemacount, 0, nil, &m->waitsemalock, nil);
runtime·thrsleep(&g->m->waitsemacount, 0, nil, &g->m->waitsemalock, nil);
else {
ns += runtime·nanotime();
// NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system.
ts.tv_nsec = 0;
ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec);
runtime·thrsleep(&m->waitsemacount, CLOCK_MONOTONIC, &ts, &m->waitsemalock, nil);
runtime·thrsleep(&g->m->waitsemacount, CLOCK_MONOTONIC, &ts, &g->m->waitsemalock, nil);
}
// reacquire lock
while(runtime·xchg(&m->waitsemalock, 1))
while(runtime·xchg(&g->m->waitsemalock, 1))
runtime·osyield();
}
// lock held (again)
if(m->waitsemacount != 0) {
if(g->m->waitsemacount != 0) {
// semaphore is available.
m->waitsemacount--;
g->m->waitsemacount--;
// spin-mutex unlock
runtime·atomicstore(&m->waitsemalock, 0);
runtime·atomicstore(&g->m->waitsemalock, 0);
return 0; // semaphore acquired
}
@ -107,7 +107,7 @@ runtime·semasleep(int64 ns)
// lock held but giving up
// spin-mutex unlock
runtime·atomicstore(&m->waitsemalock, 0);
runtime·atomicstore(&g->m->waitsemalock, 0);
return -1;
}
@ -193,6 +193,7 @@ void
runtime·mpreinit(M *mp)
{
mp->gsignal = runtime·malg(32*1024);
mp->gsignal->m = mp;
}
// Called to initialize a new m (including the bootstrap m).
@ -201,7 +202,7 @@ void
runtime·minit(void)
{
// Initialize signal handling
runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024);
runtime·signalstack((byte*)g->m->gsignal->stackguard - StackGuard, 32*1024);
runtime·sigprocmask(SIG_SETMASK, sigset_none);
}