mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
edc19fa8825a33d9f8069b97c2ff3ea552470ec2
Два дефекта в источнике времени, на котором стоят абсолютные дедлайны пейсинга
TX: планировщик TX_CHRONO и отправитель DUC ведут по нему сетку, и скачок часов
для них означает не потерю точности, а остановку выдачи.
* Windows: (V * 1000000) div QPCFreq переполняет Int64 на 9.223e12 тиках — при
типовой для Windows 8+ частоте QPC 10 МГц это 10.7 суток аптайма, дальше
разрыв повторяется каждые 21.35 суток (2^64/10^6). Между разрывами функция
линейна, поэтому страдает не «всякая машина старше N суток», а сессия,
пережившая сам момент скачка: время уходит в большой минус, NextDueUs
становится недостижим, маркеры TX_CHRONO прекращаются до перезапуска, долг
TCI уходит в минус, а проверки вида `FTxLastRxUs > 0` перестают срабатывать.
★Мест было ДВА: PlatformUtils.MonotonicUs и локальная ClockUs в потоке
отправителя DUC (win-ветка HPSDRNetwork) — вторая пейсит ВСЕ передачи на
Windows, не только TCI: WaitUntil на переполненной разности выходит сразу,
пакеты уходят без выдержки, очередь опустошается пачкой и сохнет.
Лечение — общая TicksToUs через частное и остаток (остаток меньше частоты,
произведение не переполняется; потолок отодвинулся на сотни тысяч лет).
* macOS: MonotonicUs проваливалась в общий Unix-{$ELSE} с fpgettimeofday, то
есть на СТЕННЫЕ часы. Шаг NTP назад — планировщик замирает до недостижимого
срока, вперёд — выдаёт пачку и начисляет фиктивный долг. Взят
mach_absolute_time + mach_timebase_info: монотонен и есть на любой версии
(clock_gettime на macOS только с 10.12), пересчёт тоже через частное/остаток —
на Apple Silicon база 125/3.
Публикация состояния часов: всё держится в ОДНОМ слове и поднимается в
initialization, до старта любых потоков. Пара «значение + флаг» на слабой
модели памяти (Windows ARM, Apple Silicon) позволяла читателю увидеть флаг
раньше значения, получить частоту 0 и вернуть время 0 — единичный ноль в
монотонных часах есть прыжок на десятки лет назад. Windows: QPCFreq, где 0 —
не выбран, >0 — частота, -1 — QPC непригоден (тогда GetTickCount64, чтобы часы
хотя бы шли). Darwin: MachBase = numer shl 32 or denom.
Стенд, секция H: совпадение со старой формулой ниже порога, ★негативный
контроль на пороге (старая даёт -922337203685 мкс, новая +922337203685),
монотонность через прежний разрыв, 100 суток на частотах 10/3.579545/24/1 МГц,
год при 24 МГц, и контракт «один источник на все потоки» — четыре потока,
~850 тыс. чтений, ни нулей, ни хода назад. Итого 274/274, test/cat 50/50.
★Чего стенд не покрывает: win- и darwin-ветки здесь не компилируются вовсе
(кросс-RTL не установлен). Их тела проверялись вырезкой в пробную программу с
подставным API — синтаксис и арифметика сходятся, живой вызов системного
счётчика остаётся за прогоном на той платформе.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bkwwyj7xVRrqnSVEseTRfV
Languages
Pascal
96.3%
Python
3%
Shell
0.6%