|
From: CN <cu...@ya...> - 2012-12-03 01:48:09
|
_st_epoll_dispatch seems to fire too often when the sleepq is not empty.
My guess is that it has something to do with granularity.
Here's some basic code to reproduce:
#include <stdio.h>
#include "st.h"
int main(int argc, char *argv[])
{
st_utime_t t1, t2;
st_set_eventsys(ST_EVENTSYS_ALT);
st_init();
for (;;) {
t1 = st_utime();
st_sleep(1);
t2 = st_utime();
fprintf(stderr, "%p MAIN diff = %llu\n", st_thread_self(), t2 - t1);
}
return 0;
}
And add some logging to event.c @ line 1244.
ie.
1243: timeout = (int) (min_timeout / 1000);
1244: if (timeout == 0 && _ST_SLEEPQ->due > _ST_LAST_CLOCK)
1245: fprintf(stderr, "%p ST diff=%llu\n", _ST_SLEEPQ, _ST_SLEEPQ->due - _ST_LAST_CLOCK);
1245: }
You'll also need "#include <stdio.h>" .
If you run the test, you'll see something like:
0x805f068 MAIN diff = 999992
0x805f068 ST diff=241
0x805f068 ST diff=222
0x805f068 ST diff=210
0x805f068 ST diff=199
0x805f068 ST diff=188
0x805f068 ST diff=177
0x805f068 ST diff=166
0x805f068 ST diff=155
0x805f068 ST diff=144
0x805f068 ST diff=133
0x805f068 ST diff=122
0x805f068 ST diff=111
0x805f068 ST diff=100
0x805f068 ST diff=89
0x805f068 ST diff=78
0x805f068 ST diff=66
0x805f068 ST diff=55
0x805f068 ST diff=44
0x805f068 ST diff=33
0x805f068 ST diff=23
0x805f068 ST diff=12
0x805f068 ST diff=1
0x805f068 MAIN diff = 1000000
The unnecessary firing gets worse when the sleepq gets longer.
My "fix" for this is to put a limit on the timeout, like so:
if (_ST_SLEEPQ->due <= _ST_LAST_CLOCK) {
timeout = 0;
} else {
min_timeout = _ST_SLEEPQ->due - _ST_LAST_CLOCK;
if (min_timeout < 300) /* magic number 300 seems to work well */
timeout = 1;
else
timeout = (int) (min_timeout / 1000);
}
Is this a bug or am I using st-threads incorrectly?
If it's a bug, is there a better way to fix it without using magic numbers?
Regards,
C.
|