Performance improvement for st_usleep.
winlinvip opened this issue · 0 comments
winlinvip commented
The resolution for epoll_wait
is ms, while the st_usleep
is us.
ST_HIDDEN void _st_epoll_dispatch(void)
{
......
if (_ST_SLEEPQ == NULL) {
timeout = -1;
} else {
min_timeout = (_ST_SLEEPQ->due <= _ST_LAST_CLOCK) ? 0 : (_ST_SLEEPQ->due - _ST_LAST_CLOCK);
timeout = (int) (min_timeout / 1000);
}
/* Check for I/O operations */
nfd = epoll_wait(_st_epoll_data->epfd, _st_epoll_data->evtlist, _st_epoll_data->evtlist_size, timeout);
int st_usleep(st_utime_t usecs)
{
......
if (usecs != ST_UTIME_NO_TIMEOUT) {
me->state = _ST_ST_SLEEPING;
_ST_ADD_SLEEPQ(me, usecs);
void _st_add_sleep_q(_st_thread_t *thread, st_utime_t timeout)
{
thread->due = _ST_LAST_CLOCK + timeout;
thread->flags |= _ST_FL_ON_SLEEPQ;
thread->heap_index = ++_ST_SLEEPQ_SIZE;
heap_insert(thread);
}
void _st_vp_check_clock(void)
{
......
now = st_utime();
elapsed = now - _ST_LAST_CLOCK;
_ST_LAST_CLOCK = now;
while (_ST_SLEEPQ != NULL) {
thread = _ST_SLEEPQ;
ST_ASSERT(thread->flags & _ST_FL_ON_SLEEPQ);
if (thread->due > now)
break;
_ST_DEL_SLEEPQ(thread);
......
/* Make thread runnable */
ST_ASSERT(!(thread->flags & _ST_FL_IDLE_THREAD));
thread->state = _ST_ST_RUNNABLE;
_ST_ADD_RUNQ(thread);
What happends when there is a lot of timer, so that the 0us<timeout<1ms
? The _st_epoll_dispatch
consumes lots of CPUs, because epoll_wait(0ms)
while the timer does not run(>0us).
当系统有非常多的timer时,会出现0us<timeout<1ms
的情况,这时候epoll会立刻返回epoll_wait(0ms)
,但是timer并不会执行(>0us)还没有到准确的唤醒时间。