
OSDEV: Itanium часть 2: One-time Construction API и сигнлтоны Майерса
GNU_Dimarik 3 минуты назад OSDEV: Itanium часть 2: One-time Construction API и сигнлтоны Майерса Простой 9 мин 19 C * C++ * Программирование * Приветствую!Часть 1Первые атомикиНовая реализация на гитхабКод тутВ этой...
<5 — 2026'da uzaya kaç SpaceX Starship fırlatması ulaşacak?
В сфере искусственного интеллекта произошло заметное событие. GNU_Dimarik 3 минуты назад OSDEV: Itanium часть 2: One-time Construction API и сигнлтоны Майерса Простой 9 мин 19 C * C++ * Программирование * Приветствую! Часть 1Первые атомикиНовая реализация на гитхабКод тутВ этой части мы рассмотрим что такое guard variables и как под капотом работают синглтоны Майерса. И так, стандарт начиная с С++11 гарантирует нам что локальные статические переменные инициализируются потокобезопасно.
Но кто и как это обеспечивает? Представьте себе вот такой код:struct Singleton { int a = 0; explicit Singleton(int val) : a(val) { a++; } static Singleton *instance() { static Singleton x(13); return } }; // ... pthread_t t1; pthread_create(&t1, nullptr, make_singleton, nullptr); pthread_t t2; pthread_create(&t2, nullptr, make_singleton, nullptr); pthread_join(t1, nullptr); pthread_join(t2, nullptr);Потока два, а объект один и конструктор должен быть вызван только однажды.
Технические детали
Itanium требует реализации следующих функций для обеспечения этого:extern "C" int __cxa_guard_acquire ( __int64_t *guard_object );Вызывается до инициализации объекта, т. в нашем случае до вызова конструктора возвращает 0 если объект уже создан и 1 если нет. extern "C" void __cxa_guard_release(__int64_t *guard_object);Устанавливает первый байт объекта guard_object в ненулевое значение.
Эта функция вызывается после успешной инициализации объекта. После установки первого байта компилятор считает что объект успешно инициализирован. Наша блокировка, захваченная функцией __cxa_guard_acquire освобождается.
extern "C" void __cxa_guard_abort(__int64_t *guard_object);Вызывается в случае если конструктор бросил исключение. Соответственно нужно освободить захваченный лок. Для начала нужно рассмотреть что из себя представляет сам guard_object.
Отраслевые последствия
Я сразу скажу что нет смысла говорить о порядке следования байтов потому что Itanium рассуждает в терминах индексов:The size of the guard variable is 64 bits. the byte at the address of the full variable) shall contain the value 0 prior to initialization of the associated variable, and 1 after initialization is complete. Usage of the other bytes of the guard variable is implementation-definedЧто означает следующее:Нулевой байт должен быть равен 0 если охраняемый объект еще не инициализирован и 1 в противном случае.
С остальными байтами мы можем делать все что захотим. Itanium говорит что компилятор делает примерно следующее, цитата:The following is pseudo-code showing how these functions can be used: if (obj_guard. first_byte == 0) { if ( __cxa_guard_acquire (&obj_guard) ) { catch (...
) { __cxa_guard_abort (&obj_guard); throw; } ... queue object destructor with __cxa_atexit() ... ; __cxa_guard_release (&obj_guard); } }Для нашего примера это превращается в следующий псевдо код:if (guard.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.





