Задайте прерывания Preemptable и задачи Nonpreemptable

Bug Finder обнаруживает гонки данных между параллельными задачами. Используя опции анализа Bug Finder, можно зафиксировать обнаружение гонки данных путем указывания, что определенные задачи имеют более высокие приоритеты над другими. Задача с более высоким приоритетом является атомарной относительно задач с более низким приоритетом и не может быть прервана теми задачами.

Эмуляция приоритетов задач

Можно задать до четырех различных приоритетов с этими опциями (с самым высоким приоритетом, перечисленным сначала):

Например, прерывания имеют самый высокий приоритет и не могут быть вытеснены другими задачами. Чтобы задать класс прерываний, которые могут быть вытеснены, понизьте их приоритет путем создания их выгружаемыми.

Примеры приоритетов задач

Рассмотрите этот пример с тремя задачами. Переменная var совместно используется этими двумя задачами task1 и task2 без любой защиты, такой как критический раздел. В зависимости от приоритетов task1 и task2, Bug Finder показывает гонку данных. Третья задача не важна для примера (и добавляется только, чтобы включать критический раздел, в противном случае обнаружение гонки данных отключено).

int var;

void begin_critical_section(void);
void end_critical_section(void);

void task1(void)  { 
    var++;
}

void task2(void)  { 
    var=0;
}

void task3(void){
    begin_critical_section();
    /* Some atomic operation */
    end_critical_section();
}

Настройте приоритеты task1 и task2 и смотрите, обнаруживается ли гонка данных. Например:

  1. Сконфигурируйте эти многозадачные опции:

  2. Запустите Bug Finder.

    Вы не видите, что данные мчатся. Начиная с task1 и task2 nonpreemptable прерывания, к совместно используемой переменной нельзя получить доступ одновременно.

  3. Измените task1 к выгружаемому прерыванию при помощи опции -preemptable-interrupts.

  4. Запустите Bug Finder снова. Вы теперь видите, что данные мчатся на совместно используемой переменной var.

Дальнейшие исследования

Измените этот пример следующими способами и смотрите эффект модификации:

  • Измените приоритеты task1 и task2.

    Например, можно оставить task1 как nonpreemptable прерывание, но изменение task2 к выгружаемому прерыванию при помощи опции -preemptable-interrupts.

    Гонка данных исчезает. Причина:

    • task1 имеет более высокий приоритет и не может быть прерван task2.

    • Операция в task2 является атомарным и не может быть прерван task1.

  • Включите средству проверки Data race including atomic operations (не включенный по умолчанию). Используйте опцию Find defects (-checkers).

    Вы видите, что данные мчатся снова. Средство проверки рассматривает все операции как потенциально неатомарные и операцию в task2 может теперь быть прерван более высокой приоритетной операцией в task1.

Попробуйте другие модификации к опциям анализа и смотрите результат средств проверки.

Смотрите также

Опции анализа Polyspace

Результаты Polyspace

Похожие темы