summaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2011-07-20 14:28:55 -0400
committerDmitriy Vyukov <dvyukov@google.com>2011-07-20 14:28:55 -0400
commite9090828a42b399cba7ebbb8f40e37d546265e26 (patch)
treed132f6839e7074613deea83616b2e081034b604f /src/pkg/runtime
parent708a006eabe159f47e379a51ffa405470cee8822 (diff)
downloadgo-e9090828a42b399cba7ebbb8f40e37d546265e26.tar.gz
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 http://codereview.appspot.com/4816041 Committer: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/chan.c34
1 files changed, 9 insertions, 25 deletions
diff --git a/src/pkg/runtime/chan.c b/src/pkg/runtime/chan.c
index 926bde723..0fdf77196 100644
--- a/src/pkg/runtime/chan.c
+++ b/src/pkg/runtime/chan.c
@@ -6,6 +6,7 @@
#include "type.h"
#define MAXALIGN 7
+#define NOSELGEN 1
static int32 debug = 0;
@@ -87,7 +88,6 @@ static SudoG* dequeue(WaitQ*, Hchan*);
static void enqueue(WaitQ*, SudoG*);
static SudoG* allocsg(Hchan*);
static void freesg(Hchan*, SudoG*);
-static uint32 fastrandn(uint32);
static void destroychan(Hchan*);
Hchan*
@@ -215,7 +215,7 @@ runtime·chansend(Hchan *c, byte *ep, bool *pres)
mysg.elem = ep;
mysg.g = g;
- mysg.selgen = g->selgen;
+ mysg.selgen = NOSELGEN;
g->param = nil;
g->status = Gwaiting;
enqueue(&c->sendq, &mysg);
@@ -243,7 +243,7 @@ asynch:
}
mysg.g = g;
mysg.elem = nil;
- mysg.selgen = g->selgen;
+ mysg.selgen = NOSELGEN;
g->status = Gwaiting;
enqueue(&c->sendq, &mysg);
runtime·unlock(c);
@@ -322,7 +322,7 @@ runtime·chanrecv(Hchan* c, byte *ep, bool *selected, bool *received)
mysg.elem = ep;
mysg.g = g;
- mysg.selgen = g->selgen;
+ mysg.selgen = NOSELGEN;
g->param = nil;
g->status = Gwaiting;
enqueue(&c->recvq, &mysg);
@@ -354,7 +354,7 @@ asynch:
}
mysg.g = g;
mysg.elem = nil;
- mysg.selgen = g->selgen;
+ mysg.selgen = NOSELGEN;
g->status = Gwaiting;
enqueue(&c->recvq, &mysg);
runtime·unlock(c);
@@ -854,7 +854,7 @@ selectgo(Select **selp)
sel->order[i] = i;
for(i=1; i<sel->ncase; i++) {
o = sel->order[i];
- j = fastrandn(i+1);
+ j = runtime·fastrand1()%(i+1);
sel->order[i] = sel->order[j];
sel->order[j] = o;
}
@@ -1151,7 +1151,9 @@ loop:
q->first = sgp->link;
// 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");
freesg(c, sgp);
goto loop;
@@ -1220,21 +1222,3 @@ freesg(Hchan *c, SudoG *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;
-}