exponenta event banner

Определение атомных операций в многозадачном коде

В коде с несколькими потоками можно использовать Polyspace ® Bug Finder™ для обнаружения скачков данных или Polyspace Code Prover™ для перечисления потенциально незащищенных общих переменных .

Чтобы определить, защищена ли переменная, совместно используемая несколькими потоками, от параллельного доступа, Polyspace проверяет, являются ли операции с переменной атомарными.

Неатомные операции

Если операция является неатомной, Polyspace считает, что операция включает в себя несколько шагов. Эти шаги не обязательно выполнять вместе и могут быть прерваны операциями в других потоках.

Например, рассмотрим эти две операции в двух различных потоках:

  • Резьба 1: var++;

    Эта операция является неатомной, поскольку она выполняется в три этапа: чтение var, приращение varи обратная запись var.

  • Резьба 2: var = 0;

    Эта операция является атомной, если размер var меньше размера слова на целевом объекте. Сведения о том, как Polyspace определяет размер слова, см. ниже.

Если две операции не защищены (используя, например, критические секции), операция во втором потоке может прервать операцию в первом потоке. Если прерывание происходит после var увеличивается в первом потоке, но перед обратной записью увеличенного значения можно увидеть неожиданные результаты.

Что полиспейс считает неатомным

Программа Code Prover рассматривает все операции как неатомные, если они не защищены, например, с помощью критических разделов. См. раздел Определение конкретных операций как атомарных.

Bug Finder считает операцию неатомной, если она может преобразовываться в несколько машинных инструкций. Например:

  • Операция может включать как операцию чтения, так и операцию записи. Например, var++ включает в себя считывание значения var, увеличивая значение на единицу и записывая увеличенное значение обратно в var.

  • Операция может включать 64-разрядную переменную на 32-разрядном целевом объекте. Например, операция

    long long var1, var2;
    var1=var2;
    включает в себя два этапа копирования содержимого var2 кому var1 по определенным целям.

    Polyspace использует размер указателя для целевого типа процессора в качестве порогового значения для вычисления атомарности. Например, если вы используете i386 В качестве целевого типа процессора размер указателя составляет 32 бита, а размер Long и Double - 64 бита. Поэтому Polyspace рассматривает возможность копирования одного long long или double переменная к другой как неатомная.

    См. также Target processor type (-target).

  • Операция может включать запись возвращаемого значения вызова функции в совместно используемую переменную. Например, операция x=func() включает в себя вызов func и запись возвращаемого значения func кому x.

Чтобы обнаружить гонки данных, в которых по крайней мере одна из двух операций прерывания является неатомной, включите средство проверки Bug Finder Data race. Чтобы снять это ограничение с средства проверки, включите Data race including atomic operations.

Определение конкретных операций как атомных

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

Используйте один из следующих методов:

  • Критические участки

    Защита группы операций с критическими секциями.

    Критический раздел начинается и заканчивается вызовами определенных функций. Для начала или завершения критических сечений или использования собственных функций можно использовать предопределенный набор примитивов.

    Группа операций в критическом разделе атомарны по отношению к другой группе операций, которые находятся в том же критическом разделе (то есть имеют одинаковую начальную и конечную функцию).

    Задание критических сечений с помощью опции Critical section details (-critical-section-begin -critical-section-end).

  • Временные исключительные задачи

    Защитите группу операций, указав определенные задачи как исключающие по времени.

    Если группа задач является исключающей по времени, все операции в одной задаче являются атомарными по отношению к операциям в других задачах.

    Укажите временное исключение с помощью параметра Temporally exclusive tasks (-temporal-exclusions-file).

  • Приоритеты задач (только для поиска ошибок)

    Защитите группу операций, указав, что определенные задачи имеют более высокие приоритеты. Например, прерывания имеют более высокие приоритеты по сравнению с циклическими задачами.

    С помощью этих опций можно указать до четырех различных приоритетов (с первым перечисленным наивысшим приоритетом):

    Все операции в задаче с более высоким приоритетом являются атомарными по отношению к операциям в задачах с более низким приоритетом. См. также раздел Определение прерываемых прерываний и неуполномоченных задач.

  • Рутинное отключение прерываний (только для поиска ошибок)

    Защитите группу операций, отключив все прерывания. Использовать опцию Disabling all interrupts (-routine-disable-interrupts -routine-enable-interrupts).

    После вызова подпрограммы для отключения прерываний все последующие операции являются атомарными до тех пор, пока не будет вызвана другая подпрограмма для повторного включения прерываний. Операции являются атомарными по отношению к операциям во всех других задачах.

Учебное пособие см. в разделе Защита общих переменных в многозадачном коде.

См. также

| | |

Связанные темы