engine: common: disable sleeptime by default for non-mobile platforms
Because it's causes issues with FPS on desktop systems and users had to manually set sleeptime 0 to get rid of this issue.
Будет не очень забавной ситуация, когда человек сохранит конфиг на ПК версии движка, а потом их скопирует на Android.
Я не уверен как можно разрешить эту проблему, не переименовывая квар. Возможно у @mittorn есть какие-то идеи.
Есть код таймера который я так и не закоммиттил
Как насчёт отдельного platform конфига?
@lewa-j кстати было бы неплохо. Писать в platform_$(Q_buildos).cfg всё что имеет флаг CVAR_PLATFORM.
Насколько мне не изменяет память, этим решением в других больших движках как раз пользуются. Что не обязательно говорит в его пользу, но как очевидное решение сойдет.
Не хочется правда заводить новых флагов для кваров. Их бы вообще привести в формат голдсорса, но этим как-нибудь позже можно заняться, вне этого PR.
Есть код таймера который я так и не закоммиттил
Если я правильно понимаю, нужны как минимум 4 разные реализации такого пробуждающего таймера:
- для Windows через win32 api.
- для дефолтных posix-совместимых ОС через pthreads.
- для linux через eventfd.
- для bsd/apple через kqueue(правда в последних версиях FreeBSD и NetBSD присутствует реализация eventfd).
Для реализации в Windows можно использовать waitable times, у них разрешение 0.1 мс, чего будет достаточно. Вообще у меня есть этот сниппет с таймерами, когда нибудь я PR сделаю. Насколько помню, я там на чем то застрял. А вот код, о котором говорил @mittorn https://pastebin.com/68uxZdgr https://pastebin.com/HSSX5i9G
Как я понимаю, после нормальной реализации таймеров можно будет полностью отказаться от квара sleeptime?
https://pastebin.com/HSSX5i9G
Код из engine/platform/linux/sys_linux.c нужно перенести в engine/platform/posix так как ничего специфичного для линукс там нет.
Как я понимаю, после нормальной реализации таймеров можно будет полностью отказаться от квара sleeptime
Думаю да, но я полагаю, что сигнальная система на pthreads может быть не самой эффективной на отдельных ОС так как pthreads везде реализованы по разному и в том же gnu/linux создание потоков и сигнальная система на pthreads медленные, поэтому если это возможно, стоит реализовать будильник на eventfd/kqueue для linux/bsd соответственно.
Не стал бы pthreads так использовать.
Лучше busy-wait loop без задержки.
На атомиках или спинлоках? Ну на винде и так можно лочить/разлочивать все на одном InterlockedExchange без всяких сигналов. То есть в основном потоке пишем в атомик 1, пока предыдущее значение не 0 крутим пустой цикл, а в будильнике после сна пишем в атомик 0.
Для реализации в Windows можно использовать waitable times
SetWaitableTimer юзает внутри себя ядерный вызов NtSetTimer, а тот внутри ntoskrnl.exe крутит спинлоки. То есть без лишней шелухи должно быть хорошее решение.
Cейчас поэкспериментировал, у waitable timers точность оказалась весьма плохая. Хотя, возможно что дело в каких то флагах.
Решил проблему с точностью таймеров, вот такой вот интересный сниппет получился:
void SetTimerHighResolution()
{
#if 0
// undocumented NT API features
HMODULE hndl = GetModuleHandle("ntdll.dll");
pNtSetTimerResolution = (pfnNtSetTimerResolution)GetProcAddress(hndl, "NtSetTimerResolution");
pNtQueryTimerResolution = (pfnNtQueryTimerResolution)GetProcAddress(hndl, "NtQueryTimerResolution");
ULONG min, max, cur;
pNtQueryTimerResolution(&min, &max, &cur);
pNtSetTimerResolution(max, 1, &cur);
#else
TIMECAPS tc;
timeGetDevCaps(&tc, sizeof(TIMECAPS));
timeBeginPeriod(tc.wPeriodMin);
#endif
}