Commit 909f3187 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov Committed by Russ Cox

runtime: eliminate false sharing on random number generators

Use machine-local random number generator instead of
racy global ones.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/4674049
parent f9f21aa1
......@@ -1221,17 +1221,6 @@ freesg(Hchan *c, SudoG *sg)
}
}
static uint32
fastrand1(void)
{
static uint32 x = 0x49f6428aUL;
x += x;
if(x & 0x80000000L)
x ^= 0x88888eefUL;
return x;
}
static uint32
fastrandn(uint32 n)
{
......@@ -1240,12 +1229,12 @@ fastrandn(uint32 n)
if(n <= 1)
return 0;
r = fastrand1();
r = runtime·fastrand1();
if(r < (1ULL<<31)-n) // avoid computing max in common case
return r%n;
max = (1ULL<<31)/n * n;
while(r >= max)
r = fastrand1();
r = runtime·fastrand1();
return r%n;
}
......@@ -18,21 +18,6 @@ extern MStats mstats; // defined in extern.go
extern volatile int32 runtime·MemProfileRate;
// Same algorithm from chan.c, but a different
// instance of the static uint32 x.
// Not protected by a lock - let the threads use
// the same random number if they like.
static uint32
fastrand1(void)
{
static uint32 x = 0x49f6428aUL;
x += x;
if(x & 0x80000000L)
x ^= 0x88888eefUL;
return x;
}
// Allocate an object of at least size bytes.
// Small objects are allocated from the per-thread cache's free lists.
// Large objects (> 32 kB) are allocated straight from the heap.
......@@ -97,7 +82,7 @@ runtime·mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed)
// pick next profile time
if(rate > 0x3fffffff) // make 2*rate not overflow
rate = 0x3fffffff;
m->mcache->next_sample = fastrand1() % (2*rate);
m->mcache->next_sample = runtime·fastrand1() % (2*rate);
profile:
runtime·setblockspecial(v);
runtime·MProf_Malloc(v, size);
......
......@@ -117,6 +117,7 @@ runtime·schedinit(void)
runtime·allm = m;
m->nomemprof++;
m->fastrand = 0x49f6428aUL + m->id;
runtime·mallocinit();
runtime·goargs();
......@@ -495,6 +496,7 @@ matchmg(void)
m->alllink = runtime·allm;
runtime·allm = m;
m->id = runtime·sched.mcount++;
m->fastrand = 0x49f6428aUL + m->id;
if(runtime·iscgo) {
CgoThreadStart ts;
......
......@@ -588,3 +588,16 @@ runtime·FuncForPC(uintptr pc, void *retf)
retf = runtime·findfunc(pc);
FLUSH(&retf);
}
uint32
runtime·fastrand1(void)
{
uint32 x;
x = m->fastrand;
x += x;
if(x & 0x80000000L)
x ^= 0x88888eefUL;
m->fastrand = x;
return x;
}
......@@ -229,6 +229,7 @@ struct M
int32 waitnextg;
int32 dying;
int32 profilehz;
uint32 fastrand;
Note havenextg;
G* nextg;
M* alllink; // on allm
......@@ -454,6 +455,7 @@ void runtime·runpanic(Panic*);
void* runtime·getcallersp(void*);
int32 runtime·mcount(void);
void runtime·mcall(void(*)(G*));
uint32 runtime·fastrand1(void);
void runtime·exit(int32);
void runtime·breakpoint(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment