Требуется ли для получения спин-блокировки сравнение-своп или достаточно свопа?

Предположим, у нас есть spinlock реализация:

struct Lock {
    locked : Atomic(bool),
}

Тогда функция разблокировки может быть:

fun unlock(lock : &Lock) {
    atomic_store(&lock.locked, false, release);
}

Но что насчет lock? Как правило, он использует сравнение и обмен, как это:

fun lock(lock : &Lock) {
    while atomic_compare_and_swap(&lock.locked, false, true, acquire) {}
}

Но разве для этого не будет достаточно свопа? Что-то вроде этого:

fun lock(lock : &Lock) {
    while atomic_swap(&lock.locked, true, acquire) {}
}

Есть ли проблемы с этим?

1 ответ

Сравнение и обмен не являются действительно необходимыми. Атомная установка флага true если это false логически эквивалентно безусловной установке его true,

Безусловный обмен может быть немного быстрее, поскольку не нужно ничего сравнивать, хотя реальная стоимость атомарной операции чтения-изменения-записи заключается в получении и блокировке строки кэша.

Вот пример C++ спинлока, который использует exchange()

#include <atomic>

class mutex {
    std::atomic<bool> flag{false};

public:
    void lock()
    {
        while (flag.exchange(true, std::memory_order_acquire));
    }

    void unlock()
    {
        flag.store(false, std::memory_order_release);
    }
};
Другие вопросы по тегам