Commit 102b5b34 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov Committed by Russ Cox

runtime: apply minor tweaks to channels

Remove complicated PRNG algorithm
(argument is limited by uint16 and can't be <= 1).
Do not require chansend/chanrecv selgen to be bumped with CAS.

R=rsc, ken
CC=golang-dev
https://golang.org/cl/4816041
parent 90f3cb13
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "type.h" #include "type.h"
#define MAXALIGN 7 #define MAXALIGN 7
#define NOSELGEN 1
static int32 debug = 0; static int32 debug = 0;
...@@ -87,7 +88,6 @@ static SudoG* dequeue(WaitQ*, Hchan*); ...@@ -87,7 +88,6 @@ static SudoG* dequeue(WaitQ*, Hchan*);
static void enqueue(WaitQ*, SudoG*); static void enqueue(WaitQ*, SudoG*);
static SudoG* allocsg(Hchan*); static SudoG* allocsg(Hchan*);
static void freesg(Hchan*, SudoG*); static void freesg(Hchan*, SudoG*);
static uint32 fastrandn(uint32);
static void destroychan(Hchan*); static void destroychan(Hchan*);
Hchan* Hchan*
...@@ -215,7 +215,7 @@ runtime·chansend(Hchan *c, byte *ep, bool *pres) ...@@ -215,7 +215,7 @@ runtime·chansend(Hchan *c, byte *ep, bool *pres)
mysg.elem = ep; mysg.elem = ep;
mysg.g = g; mysg.g = g;
mysg.selgen = g->selgen; mysg.selgen = NOSELGEN;
g->param = nil; g->param = nil;
g->status = Gwaiting; g->status = Gwaiting;
enqueue(&c->sendq, &mysg); enqueue(&c->sendq, &mysg);
...@@ -243,7 +243,7 @@ asynch: ...@@ -243,7 +243,7 @@ asynch:
} }
mysg.g = g; mysg.g = g;
mysg.elem = nil; mysg.elem = nil;
mysg.selgen = g->selgen; mysg.selgen = NOSELGEN;
g->status = Gwaiting; g->status = Gwaiting;
enqueue(&c->sendq, &mysg); enqueue(&c->sendq, &mysg);
runtime·unlock(c); runtime·unlock(c);
...@@ -322,7 +322,7 @@ runtime·chanrecv(Hchan* c, byte *ep, bool *selected, bool *received) ...@@ -322,7 +322,7 @@ runtime·chanrecv(Hchan* c, byte *ep, bool *selected, bool *received)
mysg.elem = ep; mysg.elem = ep;
mysg.g = g; mysg.g = g;
mysg.selgen = g->selgen; mysg.selgen = NOSELGEN;
g->param = nil; g->param = nil;
g->status = Gwaiting; g->status = Gwaiting;
enqueue(&c->recvq, &mysg); enqueue(&c->recvq, &mysg);
...@@ -354,7 +354,7 @@ asynch: ...@@ -354,7 +354,7 @@ asynch:
} }
mysg.g = g; mysg.g = g;
mysg.elem = nil; mysg.elem = nil;
mysg.selgen = g->selgen; mysg.selgen = NOSELGEN;
g->status = Gwaiting; g->status = Gwaiting;
enqueue(&c->recvq, &mysg); enqueue(&c->recvq, &mysg);
runtime·unlock(c); runtime·unlock(c);
...@@ -854,7 +854,7 @@ selectgo(Select **selp) ...@@ -854,7 +854,7 @@ selectgo(Select **selp)
sel->order[i] = i; sel->order[i] = i;
for(i=1; i<sel->ncase; i++) { for(i=1; i<sel->ncase; i++) {
o = sel->order[i]; o = sel->order[i];
j = fastrandn(i+1); j = runtime·fastrand1()%(i+1);
sel->order[i] = sel->order[j]; sel->order[i] = sel->order[j];
sel->order[j] = o; sel->order[j] = o;
} }
...@@ -1151,7 +1151,9 @@ loop: ...@@ -1151,7 +1151,9 @@ loop:
q->first = sgp->link; q->first = sgp->link;
// if sgp is stale, ignore it // if sgp is stale, ignore it
if(!runtime·cas(&sgp->g->selgen, sgp->selgen, sgp->selgen + 1)) { if(sgp->selgen != NOSELGEN &&
(sgp->selgen != sgp->g->selgen ||
!runtime·cas(&sgp->g->selgen, sgp->selgen, sgp->selgen + 2))) {
//prints("INVALID PSEUDOG POINTER\n"); //prints("INVALID PSEUDOG POINTER\n");
freesg(c, sgp); freesg(c, sgp);
goto loop; goto loop;
...@@ -1220,21 +1222,3 @@ freesg(Hchan *c, SudoG *sg) ...@@ -1220,21 +1222,3 @@ freesg(Hchan *c, SudoG *sg)
c->free = sg; c->free = sg;
} }
} }
static uint32
fastrandn(uint32 n)
{
uint32 max, r;
if(n <= 1)
return 0;
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 = runtime·fastrand1();
return r%n;
}
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