В Дарвине стандартный clock_gettime(CLOCK_MONOTONIC)
POSIX clock_gettime(CLOCK_MONOTONIC)
недоступен. Вместо этого монотонный таймер с самым высоким разрешением получается через функцию mach_absolute_time
из mach/mach_time.h
.
Возвращенный результат может быть нескорректированным количеством тактов от процессора, и в этом случае единицы времени могут быть странным кратным. Например, на процессоре с тактовым отсчетом 33 МГц Дарвин возвращает 1000000000/33333335 как точные единицы возвращаемого результата (т. mach_absolute_time
значение mach_absolute_time
на эту дробь, чтобы получить значение наносекунды).
Обычно мы хотим преобразовать точные метки в "стандартные" (десятичные) единицы, но, к сожалению, наивное умножение абсолютного времени на дробь переполнится даже в 64-битной арифметике. Это ошибка, в mach_absolute_time
попадает единственный фрагмент документации Apple по mach_absolute_time
(Технические вопросы и ответы QA1398). 1
Как мне написать функцию, которая правильно использует mach_absolute_time
?
- Обратите внимание, что это не теоретическая проблема: пример кода в QA1398 полностью не работает на Mac на базе PowerPC. На Intel Macs
mach_timebase_info
всегда возвращает 1/1 в качестве коэффициента масштабирования, потому что счетчик необработанныхmach_timebase_info
ЦП ненадежен (динамическоеmach_timebase_info
скорости), поэтому API выполняет масштабирование за вас. На компьютерах PowerPC Macmach_timebase_info
возвращает либо 1000000000/33333335, либо 1000000000/25000000, поэтому предоставляемый Apple код явно переполняется каждые несколько минут. К сожалению.