Класс QAtomicPointer
Класс QAtomicPointer — это шаблонный класс, предоставляющий платформенно-независимые атомарные операции с указателями. Подробнее...
| Заголовок: | #include <QAtomicPointer> |
| qmake: | QT += core |
| С тех пор: | Qt 4.4 |
| Наследует: | QBasicAtomicPointer |
Публичные функции
| QAtomicPointer(T *value = nullptr) | |
| QAtomicPointer(const QAtomicPointer<T> &other) | |
| T * | fetchAndAddAcquire(qptrdiff valueToAdd) |
| T * | fetchAndAddOrdered(qptrdiff valueToAdd) |
| T * | fetchAndAddRelaxed(qptrdiff valueToAdd) |
| T * | fetchAndAddRelease(qptrdiff valueToAdd) |
| T * | fetchAndStoreAcquire(T *newValue) |
| T * | fetchAndStoreOrdered(T *newValue) |
| T * | fetchAndStoreRelaxed(T *newValue) |
| T * | fetchAndStoreRelease(T *newValue) |
| T * | load() const |
| T * | loadAcquire() const |
| void | store(T *newValue) |
| void | storeRelease(T *newValue) |
| bool | testAndSetAcquire(T *expectedValue, T *newValue) |
| bool | testAndSetOrdered(T *expectedValue, T *newValue) |
| bool | testAndSetRelaxed(T *expectedValue, T *newValue) |
| bool | testAndSetRelease(T *expectedValue, T *newValue) |
| QAtomicPointer<T> & | operator=(const QAtomicPointer<T> &other) |
Статические публичные члены
| bool | isFetchAndAddNative() |
| bool | isFetchAndAddWaitFree() |
| bool | isFetchAndStoreNative() |
| bool | isFetchAndStoreWaitFree() |
| bool | isTestAndSetNative() |
| bool | isTestAndSetWaitFree() |
Макросы
Подробное описание
Класс QAtomicPointer — это шаблонный класс, предоставляющий платформенно-независимые атомарные операции с указателями.
Для атомарных операций с целыми числами см. класс QAtomicInteger.
Атомарная операция — это сложная операция, которая завершается без прерывания. Класс QAtomicPointer предоставляет атомарные операции «проверка и установка», «получение и сохранение» и «получение и прибавление» для указателей.
Атомарный API
Порядок памяти
Класс QAtomicPointer предоставляет несколько реализаций атомарных функций «проверка и установка», «получение и сохранение» и «получение и прибавление». Каждая реализация определяет семантику порядка памяти, которая описывает, как процессор выполняет операции доступа к памяти, окружающие атомарную инструкцию. Поскольку во многих современных архитектурах допускается выполнение операций вне очереди и порядок памяти, для обеспечения правильной работы приложения на всех процессорах необходимо использовать соответствующую семантику.
- Relaxed — порядок памяти не определён, оставляя компилятору и процессору свободу переупорядочения операций доступа к памяти.
- Acquire — доступ к памяти, следующий за атомарной операцией (в порядке программы), не может быть переупорядочен перед атомарной операцией.
- Release — доступ к памяти перед атомарной операцией (в порядке программы) не может быть переупорядочен после атомарной операции.
- Ordered — сочетание семантики Acquire и Release.
Проверка и установка
Если текущее значение QAtomicPointer совпадает с ожидаемым значением, функции проверки и установки присваивают новое значение QAtomicPointer и возвращают true. Если значения не совпадают, эти функции ничего не делают и возвращают false. Эта операция эквивалентна следующему коду:
if (currentValue == expectedValue) {
currentValue = newValue;
return true;
}
return false; Существует 4 функции проверки и установки: testAndSetRelaxed(), testAndSetAcquire(), testAndSetRelease() и testAndSetOrdered(). См. выше для объяснения различных семантик порядка памяти.
Получение и сохранение
Атомарные функции получения и сохранения считывают текущее значение QAtomicPointer, а затем присваивают новое значение, возвращая исходное значение. Эта операция эквивалентна следующему коду:
T *originalValue = currentValue; currentValue = newValue; return originalValue;
Существует 4 функции fetch-and-store: fetchAndStoreRelaxed(), fetchAndStoreAcquire(), fetchAndStoreRelease(), и fetchAndStoreOrdered(). См. выше для объяснения различных семантик порядка памяти.
Fetch-and-add
Функции атомарного fetch-and-add считывают текущее значение QAtomicPointer, а затем добавляют заданное значение к текущему значению, возвращая исходное значение. Эта операция эквивалентна следующему коду:
T *originalValue = currentValue; currentValue += valueToAdd; return originalValue;
Существует 4 функции fetch-and-add: fetchAndAddRelaxed(), fetchAndAddAcquire(), fetchAndAddRelease(), и fetchAndAddOrdered(). См. выше для объяснения различных семантик порядка памяти.
Тесты функций атомарного API
Предоставление независимого от платформы атомарного API, работающего на всех процессорах, является сложной задачей. API, предоставляемый QAtomicPointer, гарантированно работает атомарно на всех процессорах. Однако, так как не все процессоры поддерживают все операции, предоставляемые QAtomicPointer, необходимо предоставить информацию о процессоре.
Вы можете проверить во время компиляции, какие функции поддерживаются вашим оборудованием, используя различные макросы. Они скажут вам, всегда ли, иногда или никогда не поддерживается конкретная операция на вашем оборудовании. Макросы имеют вид Q_ATOMIC_POINTER_OPERATION_IS_HOW_NATIVE. OPERATION — это одна из TEST_AND_SET, FETCH_AND_STORE или FETCH_AND_ADD, а HOW — одна из ALWAYS, SOMETIMES или NOT. Для каждой операции всегда будет определён ровно один макрос. Например, если Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE определён, ни Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE, ни Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE не будут определены.
Операция, которая выполняется за постоянное время, называется бесперебойной. Такие операции не реализуются с помощью блокировок или циклов любого рода. Для атомарных операций, которые всегда поддерживаются и являются бесперебойными, Qt определяет Q_ATOMIC_POINTER_OPERATION_IS_WAIT_FREE в дополнение к Q_ATOMIC_POINTER_OPERATION_IS_ALWAYS_NATIVE.
В тех случаях, когда атомарная операция поддерживается только в новых поколениях процессоров, QAtomicPointer также предоставляет способ проверки на выполнение того, что поддерживается вашим оборудованием во время выполнения с помощью функций isTestAndSetNative(), isFetchAndStoreNative() и isFetchAndAddNative(). Бесперебойные реализации могут быть обнаружены с помощью функций isTestAndSetWaitFree(), isFetchAndStoreWaitFree() и isFetchAndAddWaitFree().
Ниже приведён полный список всех макросов функций для QAtomicPointer:
- Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
- Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
- Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
- Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
- Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
- Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
- Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
См. также QAtomicInteger.
Документация по функциям-членам
QAtomicPointer::QAtomicPointer(T *value = nullptr)
Создаёт QAtomicPointer с заданным значением value.
QAtomicPointer::QAtomicPointer(const QAtomicPointer<T> &other)
Создаёт копию other.
T *QAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd)
Атомарное fetch-and-add.
Считывает текущее значение этого QAtomicPointer, затем добавляет valueToAdd к текущему значению и возвращает исходное значение.
Эта функция использует семантику порядка памяти acquire, которая гарантирует, что доступ к памяти, следующий за атомарной операцией (в порядке программы), не может быть переупорядочен до атомарной операции.
T *QAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd)
Атомарное fetch-and-add.
Считывает текущее значение этого QAtomicPointer, затем добавляет valueToAdd к текущему значению и возвращает исходное значение.
Эта функция использует семантику порядка памяти ordered, которая гарантирует, что доступ к памяти до и после атомарной операции (в порядке программы) не может быть переупорядочен.
T *QAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd)
Атомарное fetch-and-add.
Считывает текущее значение этого QAtomicPointer, затем добавляет valueToAdd к текущему значению и возвращает исходное значение.
Эта функция использует семантику порядка памяти relaxed, оставляя компилятору и процессору свободу переупорядочивать доступ к памяти.
T *QAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd)
Атомарное fetch-and-add.
Считывает текущее значение этого QAtomicPointer, затем добавляет valueToAdd к текущему значению и возвращает исходное значение.
Эта функция использует семантику порядка памяти release, которая гарантирует, что доступ к памяти до атомарной операции (в порядке программы) не может быть переупорядочен после атомарной операции.
T *QAtomicPointer::fetchAndStoreAcquire(T *newValue)
Атомарное fetch-and-store.
Считывает текущее значение этого QAtomicPointer и присваивает ему newValue, возвращая исходное значение.
Эта функция использует семантику порядка памяти acquire, которая гарантирует, что доступ к памяти, следующий за атомарной операцией (в порядке программы), не может быть переупорядочен до атомарной операции.
T *QAtomicPointer::fetchAndStoreOrdered(T *newValue)
Атомарное fetch-and-store.
Считывает текущее значение этого QAtomicPointer и присваивает ему newValue, возвращая исходное значение.
Эта функция использует семантику порядка памяти ordered, которая гарантирует, что доступ к памяти до и после атомарной операции (в порядке программы) не может быть переупорядочен.
T *QAtomicPointer::fetchAndStoreRelaxed(T *newValue)
Атомарное fetch-and-store.
Считывает текущее значение этого QAtomicPointer и присваивает ему newValue, возвращая исходное значение.
Эта функция использует семантику порядка памяти relaxed, оставляя компилятору и процессору свободу переупорядочивать доступ к памяти.
T *QAtomicPointer::fetchAndStoreRelease(T *newValue)
Атомарное fetch-and-store.
Считывает текущее значение этого QAtomicPointer и присваивает ему newValue, возвращая исходное значение.
Эта функция использует семантику порядка памяти release, которая гарантирует, что доступ к памяти до атомарной операции (в порядке программы) не может быть переупорядочен после атомарной операции.
[static] bool QAtomicPointer::isFetchAndAddNative()
Возвращает true значение true, если fetch-and-add реализован с помощью атомарных инструкций процессора, иначе false.
[static] bool QAtomicPointer::isFetchAndAddWaitFree()
Возвращает true значение true, если атомарное fetch-and-add является бесперебойным, иначе false.
[static] bool QAtomicPointer::isFetchAndStoreNative()
Возвращает true значение true, если fetch-and-store реализован с помощью атомарных инструкций процессора, иначе false.
[static] bool QAtomicPointer::isFetchAndStoreWaitFree()
Возвращает true если атомарная операция fetch-and-store не блокируется, в противном случае возвращает false.
[static] bool QAtomicPointer::isTestAndSetNative()
Возвращает true если операция test-and-set реализована с использованием атомарных инструкций процессора, в противном случае возвращает false.
[static] bool QAtomicPointer::isTestAndSetWaitFree()
Возвращает true если атомарная операция test-and-set не блокируется, в противном случае возвращает false.
T *QAtomicPointer::load() const
Атомарно загружает значение этого QAtomicPointer с использованием релаксированного порядка памяти. Значение не изменяется, но нет гарантии, что оно останется неизменным.
См. также store() и loadAcquire().
T *QAtomicPointer::loadAcquire() const
Атомарно загружает значение этого QAtomicPointer с использованием порядка памяти «Acquire». Значение не изменяется, но нет гарантии, что оно останется неизменным.
void QAtomicPointer::store(T *newValue)
Атомарно сохраняет значение newValue в этом атомарном типе с использованием релаксированного порядка памяти.
См. также storeRelease() и load().
void QAtomicPointer::storeRelease(T *newValue)
Атомарно сохраняет значение newValue в этом атомарном типе с использованием порядка памяти «Release».
bool QAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue)
Атомарное test-and-set.
Если текущее значение этого QAtomicPointer равно expectedValue, test-and-set присваивает newValue этому QAtomicPointer и возвращает true. Если значения не совпадают, функция ничего не делает и возвращает false.
Эта функция использует семантику порядка памяти acquire, что гарантирует, что доступ к памяти после атомарной операции (в порядке программы) не может быть переупорядочен до атомарной операции.
bool QAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue)
Атомарное test-and-set.
Если текущее значение этого QAtomicPointer равно expectedValue, test-and-set присваивает newValue этому QAtomicPointer и возвращает true. Если значения не совпадают, функция ничего не делает и возвращает false.
Эта функция использует семантику ordered порядка памяти, которая гарантирует, что доступ к памяти до и после атомарной операции (в порядке программы) не может быть переупорядочен.
bool QAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue)
Атомарное test-and-set.
Если текущее значение этого QAtomicPointer равно expectedValue, test-and-set присваивает newValue этому QAtomicPointer и возвращает true. Если значения не совпадают, функция ничего не делает и возвращает false.
Эта функция использует семантику relaxed порядка памяти, позволяя компилятору и процессору свободно переупорядочивать доступ к памяти.
bool QAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue)
Атомарное test-and-set.
Если текущее значение этого QAtomicPointer равно expectedValue, test-and-set присваивает newValue этому QAtomicPointer и возвращает true. Если значения не совпадают, функция ничего не делает и возвращает false.
Эта функция использует семантику release порядка памяти, которая гарантирует, что доступ к памяти перед атомарной операцией (в порядке программы) не может быть переупорядочен после атомарной операции.
QAtomicPointer<T> &QAtomicPointer::operator=(const QAtomicPointer<T> &other)
Присваивает other этому QAtomicPointer и возвращает ссылку на этот QAtomicPointer.
Документация макросов
Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
Этот макрос определён тогда и только тогда, когда ваш процессор поддерживает атомарную операцию fetch-and-add для указателей.
Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
Этот макрос определён, когда аппаратное обеспечение не поддерживает атомарную операцию fetch-and-add для указателей.
Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
Этот макрос определён, когда только определённые поколения процессоров поддерживают атомарную операцию fetch-and-add для указателей. Используйте функцию QAtomicPointer::isFetchAndAddNative(), чтобы проверить, что поддерживает ваш процессор.
Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
Этот макрос определён вместе с Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE для указания того, что атомарная операция fetch-and-add для указателей не блокируется.
Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
Этот макрос определён тогда и только тогда, когда ваш процессор поддерживает атомарную операцию fetch-and-store для указателей.
Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
Этот макрос определён, когда аппаратное обеспечение не поддерживает атомарную операцию fetch-and-store для указателей.
Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
Этот макрос определён, когда только определённые поколения процессоров поддерживают атомарную операцию fetch-and-store для указателей. Используйте функцию QAtomicPointer::isFetchAndStoreNative(), чтобы проверить, что поддерживает ваш процессор.
Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
Этот макрос определён вместе с Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE для указания того, что атомарная операция fetch-and-store для указателей не блокируется.
Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
Этот макрос определён тогда и только тогда, когда ваш процессор поддерживает атомарную операцию test-and-set для указателей.
Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
Этот макрос определён, когда аппаратное обеспечение не поддерживает атомарную операцию test-and-set для указателей.
Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
Этот макрос определён, когда только определённые поколения процессоров поддерживают атомарную операцию test-and-set для указателей. Используйте функцию QAtomicPointer::isTestAndSetNative(), чтобы проверить, что поддерживает ваш процессор.
Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
Этот макрос определён вместе с Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE для указания того, что атомарная операция test-and-set для указателей не блокируется.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.12/qatomicpointer.html