Usleep() and QTimer resolution in Linux
-
A small question regarding timing issues in Qt.
I'm running a custom linux kernel (Preemptible Kernel) with a Qt application on embedded device.
I just tested these lines of code:
@
elapsedTimer.start();
usleep(100*1000);
qDebug() << "SLEEP: " << elapsedTimer.elapsed() << " ms.";
@Output:
@
SLEEP: 109 ms.
SLEEP: 109 ms.
SLEEP: 109 ms.
SLEEP: 110 ms.
SLEEP: 109 ms.
@But when I use a QTimer connected with a slot and timeout of 100ms I get the following output:
@
void MainWindow::printInfo()
{
qDebug() << "SLEEP: " << elapsedTimer.elapsed() << " ms.";
elapsedTimer.start();
}
@@
SLEEP: 99 ms.
SLEEP: 99 ms.
SLEEP: 100 ms.
SLEEP: 99 ms.
SLEEP: 99 ms.
SLEEP: 99 ms.
SLEEP: 99 ms.
@Resolution seems to be 1ms in both cases and is good enough, but using usleep takes nearly 10% extra time. So what is causing this?
Is this because usleep() is the MINIMUM amount of time the application sleeps? And QTimer tries to use exact timing?
Thanks
-
Can you try running the same example on a "standard" kernel on a PC? Is the difference the same there?
You would need to check the source code of QTimer and usleep, but I guess it's about context switching/ thread scheduling.
-
Just tested on laptop with Ubuntu and stock kernel.
The difference is non-existent it seems in this configuration:
usleep()
@SLEEP: 100 ms.
SLEEP: 102 ms.
SLEEP: 100 ms.
SLEEP: 104 ms. @QTimer
@SLEEP: 99 ms.
SLEEP: 99 ms.
SLEEP: 99 ms.
SLEEP: 100 ms.
SLEEP: 100 ms.
SLEEP: 99 ms. @ -
Now it looks even more like a context switch issue :)
My guess: when using QTimer, your thread is always active, so it fires on time. When usleeping, once the given time passes, the thread needs to wake up, which takes additional time.