В коде с несколькими потоками можно использовать 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).
После вызова подпрограммы для отключения прерываний все последующие операции являются атомарными до тех пор, пока не будет вызвана другая подпрограмма для повторного включения прерываний. Операции являются атомарными по отношению к операциям во всех других задачах.
Учебное пособие см. в разделе Защита общих переменных в многозадачном коде.
Critical section details (-critical-section-begin -critical-section-end) | Cyclic tasks (-cyclic-tasks) | Interrupts (-interrupts) | Temporally exclusive tasks (-temporal-exclusions-file)