Проблема, о которой вы спрашивали больше всего: if (t.QuadPart < time_.QuadPart)
должно быть следующим: if (t.QuadPart - time_.QuadPart < 0)
Причина этого заключается в том, что вы хотите искать перенос в относительном, а не абсолютном времени.Относительное время будет перенесено (1 раз << 63) единиц времени после обращения к QPC.Абсолютное время <em>может переносить (1 раз << 63) единицы времени после перезагрузки, но оно может переноситься в любое другое время, когда это ощущается, это не определено.</p>
QPC немного ошибочен в некоторых системах (например, в старых QPC на основе RDTSC в ранних многоядерных процессорах), поэтому может быть желательно разрешить небольшие отрицательные дельты времени, например: if (t.QuadPart - time_.QuadPart < -1000000)
// time wrap
Фактическая упаковка даст очень большие отрицательные дельты времени, так что это безопасно.Это не должно быть необходимо в современных системах, но доверие к Microsoft редко является хорошей идеей.
... Тем не менее, большая проблема с временным переносом заключается в том, что ticks_to_wait
, ticks_passed
и ticks_left
имеют тип int, а не LARGE_INT или long longкак они должны быть.Это делает большую часть этого кода переносом, если задействованы какие-либо значимые периоды времени - и «значительный» в этом контексте зависит от платформы, он может быть порядка 1 секунды в некоторых (редких в наши дни) случаях или даже меньше в некоторыхгипотетическая система будущего.
Другие проблемы:
if (time_.QuadPart != 0)
Ноль не является особым значением и не должен рассматриваться как таковой.Я предполагаю, что код совмещает QPC, возвращая нулевое время с возвращаемым значением QPC, равным нулю.Возвращаемое значение - это не 64-битное время, переданное указателем, это BOOL, который фактически возвращает QPC.
Кроме того, этот цикл Sleep (0) является глупым - он настроен на корректную работу только на определенном уровне конкуренции и конкретной производительности ЦП для каждого потока.Если вам нужно разрешение, это ужасная идея, и если вам не нужно разрешение, тогда вся эта функция должна была быть всего лишь одним вызовом Sleep.