std :: atomic обеспечивает сравнение Compare_exchange_strong (a, b), если базовое значение в настоящее время равно "a", и если да, то заменяет его на "b" атомарным / потокобезопасным способом.
Существует ли какой-либо атомарный способ без блокировки выполнить аналогичную операцию, но вместо проверки на равенство с "b" он будет обрабатывать "b" как флаг и выполнять замену, если базовое значение имеет этот флаг?
Итак, в принципе, что-то вроде
bool compare_exchange_flags(std::atomic<int>& underlying, int& flag, int replacement)
{
auto tmp = underlying.load();
if((tmp & flag) == flag) // only perform replacement if flag is set
{
flag = tmp; // emulate compare_exchange_strong, where expected value is replaced with actual value
underlying = replacement;
return true;
} else {
flag = underlying.load();
return false;
}
}
только в версии, которая ... ну, на самом деле работает;) (приведенные выше операции совсем не атомарны, конечно)
Спасибо!
Для контекста: Это для шины сообщений.Эта шина имеет области памяти, связанные с некоторыми состояниями (такими как READABLE, WRITEABLE).
Каждое состояние должно быть улучшено с помощью некоторых флагов - например, состояние может быть просто «WRITEABLE», то есть средство записи может свободнозаписать данные во фрагмент (читатели в данный момент крутятся / заняты опросом).Или это может быть «WRITEABLE | SIGNALED», что подразумевает, что писатель может получить эту память для записи, но должен вызвать событие после записи данных, чтобы уведомить читателей.
Итак (ОЧЕНЬ концептуально это нене фактический код - просто для грубой демонстрации) что-то вроде
void send(...)
{
auto expected = WRITEABLE;
if(compare_exchange_flags(status, expected, WRITE_RESERVED))
{
// ... write data ...
status = WRITTEN;
if((expected & SIGNALED) = SIGNALED)
wakeUpReaders();
} else {
tryAnotherRegion();
}
}