Commit cb32ea9c authored by Russ Cox's avatar Russ Cox

runtime: replace bubble sort with heap sort in select

R=golang-dev, agl
CC=golang-dev
https://golang.org/cl/7304106
parent a6db2a85
...@@ -840,7 +840,7 @@ static void* ...@@ -840,7 +840,7 @@ static void*
selectgo(Select **selp) selectgo(Select **selp)
{ {
Select *sel; Select *sel;
uint32 o, i, j; uint32 o, i, j, k;
Scase *cas, *dfl; Scase *cas, *dfl;
Hchan *c; Hchan *c;
SudoG *sg; SudoG *sg;
...@@ -874,12 +874,42 @@ selectgo(Select **selp) ...@@ -874,12 +874,42 @@ selectgo(Select **selp)
} }
// sort the cases by Hchan address to get the locking order. // sort the cases by Hchan address to get the locking order.
// simple heap sort, to guarantee n log n time and constant stack footprint.
for(i=0; i<sel->ncase; i++) { for(i=0; i<sel->ncase; i++) {
c = sel->scase[i].chan; j = i;
for(j=i; j>0 && sel->lockorder[j-1] >= c; j--) c = sel->scase[j].chan;
sel->lockorder[j] = sel->lockorder[j-1]; while(j > 0 && sel->lockorder[k=(j-1)/2] < c) {
sel->lockorder[j] = sel->lockorder[k];
j = k;
}
sel->lockorder[j] = c; sel->lockorder[j] = c;
} }
for(i=sel->ncase; i-->0; ) {
c = sel->lockorder[i];
sel->lockorder[i] = sel->lockorder[0];
j = 0;
for(;;) {
k = j*2+1;
if(k >= i)
break;
if(k+1 < i && sel->lockorder[k] < sel->lockorder[k+1])
k++;
if(c < sel->lockorder[k]) {
sel->lockorder[j] = sel->lockorder[k];
j = k;
continue;
}
break;
}
sel->lockorder[j] = c;
}
/*
for(i=0; i+1<sel->ncase; i++)
if(sel->lockorder[i] > sel->lockorder[i+1]) {
runtime·printf("i=%d %p %p\n", i, sel->lockorder[i], sel->lockorder[i+1]);
runtime·throw("select: broken sort");
}
*/
sellock(sel); sellock(sel);
loop: loop:
......
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