I am currently investigating an instance where
TLazMonitor massively underperforms on Windows, but works fine on Mac and Linux.
Before creating an issue and proposing a patch on GitLab, I need more information.
I came across this issue while using
TLazThreadedQueue from the unit
LazCollections. Pushing and popping items worked very slowly.
I discovered that
TLazThreadedQueue uses a
TLazMonitor object internally and that
TLazMonitor does busy-sleeping through calls to
sleep(1) and
sleep(0). I believe the calls to
sleep(1) are problematic since the default timer resolution, on Windows,
is around 16 ms.
I can work around this issue by calling
timeBeginPeriod/timeEndPeriod and passing 1 ms as the argument. However, this fix is unacceptable. Depending on the version of Windows,
timeBeginPeriod/
timeEndPeriod may affect the whole system or the whole application, leading to unwanted side effects. In some instances, Windows does not even guarantee that the higher resolution will be honored.
By replacing the
TLazMonitor object with a
TCriticalSection,
TLazThreadedQueue becomes much faster. I have tested this change on Windows, Mac and Linux, and it seems to work just fine.
I have tried to understand why
TLazMonitor (which is a child of
TCriticalSection) is used instead of
TCriticalSection directly, but could not find any answers. Moreover,
TLazMonitor is barely used in Lazarus' codebase and barely mentioned anywhere on the Internet.
Does someone know why one might want to use
TLazMonitor over
TCriticalSection?