Как реализовать TAS («проверить и установить»)? - PullRequest
0 голосов
/ 27 февраля 2020

Кто-нибудь знал реализацию TAS?

Этот код впоследствии должен быть в состоянии защитить код между получением и освобождением от многопоточной потери состояний.

typedef volatile long lock_t;

void acquire(lock_t* lock){
    while(TAS(lock))
        ;
}

void release(lock_t* lock){
    *lock = 0;
}

lock_t REQ_lock = 0;

int main(){
    acquire(&REQ_lock);
    //not Atomar Code
    release(&REQ_lock);
}

Ответы [ 3 ]

3 голосов
/ 27 февраля 2020

Стандарт C11 переносит атомы c типов в язык.

Среди них есть тип atomic_flag, который имеет связанную функцию atomic_flag_test_and_set Вот он из стандарта:

C11 рабочий проект, раздел 7.17.8.1:

Сводка

#include <stdatomic.h>
_Bool atomic_flag_test_and_set(
    volatile atomic_flag *object);
_Bool atomic_flag_test_and_set_explicit(
    volatile atomic_flag *object,memory_order order);

Описание

Наборы атома значение, указанное объектом для истины. Память зависит от стоимости заказа. Эти операции являются атомами c операции чтения-изменения-записи

Возвращает

Атомно, значение объекта непосредственно перед эффектами.

И вместе с ним вам понадобятся родственные операции, atomic_flag_clear

Раздел 7.17.8.2:

Конспект

#include <stdatomic.h>
void atomic_flag_clear(volatile atomic_flag *object);
void atomic_flag_clear_explicit(
    volatile atomic_flag *object, memory_order order);

Описание

Аргумент порядка не должен быть ни memory_order_acquire, ни memory_order_acq_rel. Атомно устанавливает значение, на которое указывает объект, в false. На память влияет значение порядка.

Возвращает

Функции atomic_flag_clear не возвращают значения

0 голосов
/ 27 февраля 2020

Да, нет. Одно из достоинств C - это максимально приблизить вас к границе машинного языка, но не дальше. Это далее.

Вы можете go для поддержки atomi c, которая предусмотрена в некотором стандарте C, но это гнездо проблем.

Написать TAS в сборка. Ограничить видимость переменных, используемых для TAS, для сдерживания. Для любой конкретной архитектуры это должно быть не более чем несколько строк сборки. Ваша программа будет содержать свою зависимость, и отсутствие сдерживания является одним из критических недостатков в последнее десятилетие C дополнений.

0 голосов
/ 27 февраля 2020

Хорошо, это должно работать. Работает для большинства 32-процессорных

#define TAS(lock) __sync_lock_test_and_set(lock, 1)
...