Получите и выпустите примитивы синхронизации в том же модуле на том же уровне абстракции
Получите и выпустите примитивы синхронизации в том же модуле на том же уровне abstraction.[1]
Это средство проверки проверяет на эти проблемы:
Пропавшие без вести блокировки.
Пропавшие без вести разблокировали.
Двойной замок.
Дважды разблокируйте.
Отсутствие блокировки происходит, когда задача вызывает разблокировать функцию прежде, чем вызвать соответствующую функцию блокировки.
В многозадачном коде функция блокировки начинает критический раздел кода, и разблокировать функция заканчивает его. Когда задача my_task
вызывает функцию блокировки my_lock
, другие задачи, вызывая my_lock
должен ожидать до my_task
вызовы соответствие разблокировали функцию. Polyspace® требует, чтобы и блокировка и разблокировала функции, должен иметь форму void func(void)
.
Чтобы найти этот дефект, необходимо задать многозадачные опции перед анализом. Чтобы задать эти опции, на панели Configuration, выбирают Multitasking.
Вызов разблокировать функции без соответствующей функции блокировки может указать на ошибку кодирования. Например, возможно, разблокировать функция не соответствует функции блокировки, которая начинает критический раздел.
Фиксация зависит от первопричины дефекта. Например, если дефект происходит из-за несоответствия между блокировкой, и разблокируйте функцию, проверяйте, что блокировка - разблокировала функциональную пару в вашей аналитической настройке Polyspace и фиксирует несоответствие.
Смотрите примеры мер ниже. Чтобы избежать проблемы, можно применить практику вызова блокировки и разблокировать функции в том же модуле на том же уровне абстракции. Например, в этом примере, func
вызывает блокировку, и разблокируйте функцию на том же уровне, но func2
не делает.
void func() { my_lock(); { // ... } my_unlock(); } void func2() { { my_lock(); // ... } my_unlock(); }
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.
void begin_critical_section(void);
void end_critical_section(void);
int global_var;
void reset(void)
{
begin_critical_section();
global_var = 0;
end_critical_section();
}
void my_task(void)
{
global_var += 1;
end_critical_section();
}
В этом примере, чтобы эмулировать многозадачное поведение, необходимо задать следующие опции:
Опция | Спецификация | |
---|---|---|
Configure multitasking manually | ||
Tasks |
| |
Critical section details | Starting routine | Ending routine |
begin_critical_section | end_critical_section |
На командной строке можно использовать следующее:
polyspace-bug-finder -entry-points my_task,reset -critical-section-begin begin_critical_section:cs1 -critical-section-end end_critical_section:cs1
Пример имеет две точки входа, my_task
и reset
. my_task
вызовы end_critical_section
прежде, чем вызвать begin_critical_section
.
Одна возможная коррекция должна вызвать функцию блокировки begin_critical_section
перед инструкциями в критическом разделе.
void begin_critical_section(void); void end_critical_section(void); int global_var; void reset(void) { begin_critical_section(); global_var = 0; end_critical_section(); } void my_task(void) { begin_critical_section(); global_var += 1; end_critical_section(); }
void begin_critical_section(void);
void end_critical_section(void);
int global_var;
void reset() {
begin_critical_section();
global_var=0;
end_critical_section();
}
void my_task(void) {
int index=0;
volatile int numCycles;
while(numCycles) {
if(index%10==0) {
begin_critical_section();
global_var ++;
}
end_critical_section();
index++;
}
}
В этом примере, чтобы эмулировать многозадачное поведение, необходимо задать следующие опции:
Опция | Спецификация | |
---|---|---|
Configure multitasking manually | ||
Tasks |
| |
Critical section details | Starting routine | Ending routine |
begin_critical_section | end_critical_section |
На командной строке можно использовать следующее:
polyspace-bug-finder -entry-points my_task,reset -critical-section-begin begin_critical_section:cs1 -critical-section-end end_critical_section:cs1
Пример имеет две точки входа, my_task
и reset
.
В while
цикл, my_task
оставляет критический раздел через вызов end_critical_section();
. В итерации while
цикл:
Если my_task
вводит if
ветвь условия, критический раздел начинается через вызов begin_critical_section
.
Если my_task
не вводит if
ветвь условия и листы while
цикл, критический раздел не начинается. Поэтому дефект Missing lock происходит.
Если my_task
не вводит if
ветвь условия и продолжается к следующей итерации while
цикл, разблокировать функциональный end_critical_section
называется снова. Дефект Double unlock происходит.
Поскольку numCycles
volatile
переменная, это может принять любое значение. Любой из случаев выше возможен. Поэтому дефект Missing lock и дефект Double unlock появляются на вызове end_critical_section
.
Пропавшие без вести разблокировали, происходит когда:
Задача вызывает функцию блокировки.
Задача заканчивается без вызова разблокировать функции.
В многозадачном коде функция блокировки начинает критический раздел кода, и разблокировать функция заканчивает его. Когда задача, my_task
, вызывает функцию блокировки, my_lock
, другие задачи, вызывая my_lock
должен ожидать до my_task
вызовы соответствие разблокировали функцию. Polyspace требует, чтобы и блокировка и разблокировала функции, должен иметь форму void func(void)
.
Чтобы найти этот дефект, перед анализом, необходимо задать многозадачные опции. На панели Configuration выберите Multitasking.
Разблокировать функция заканчивает критический раздел так, чтобы другие ожидающие задачи могли ввести критический раздел. Отсутствие разблокировало функцию, может привести к задачам, блокированным в течение ненужного отрезка времени.
Идентифицируйте критический раздел кода, то есть, раздел, что вы хотите быть выполненными как атомарный блок. В конце этого раздела вызовите разблокировать функцию, которая соответствует функции блокировки, используемой в начале раздела.
Могут быть другие причины и соответствующие меры для дефекта. Возможно, вы вызвали неправильное, разблокировали функцию. Проверяйте, что блокировка - разблокировала функциональную пару в вашей аналитической настройке Polyspace и фиксирует несоответствие.
Смотрите примеры мер ниже. Чтобы избежать проблемы, можно применить практику вызова блокировки и разблокировать функции в том же модуле на том же уровне абстракции. Например, в этом примере, func
вызывает блокировку, и разблокируйте функцию на том же уровне, но func2
не делает.
void func() { my_lock(); { // ... } my_unlock(); } void func2() { { my_lock(); // ... } my_unlock(); }
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.
void begin_critical_section(void);
void end_critical_section(void);
int global_var;
void reset()
{
begin_critical_section();
global_var = 0;
end_critical_section();
}
void my_task(void)
{
begin_critical_section();
global_var += 1;
}
В этом примере, чтобы эмулировать многозадачное поведение, задают следующие опции:
Опция | Спецификация | |
---|---|---|
Configure multitasking manually | ||
Tasks |
| |
Critical section details | Starting routine | Ending routine |
begin_critical_section | end_critical_section |
На командной строке можно использовать следующее:
polyspace-bug-finder -entry-points my_task,reset -critical-section-begin begin_critical_section:cs1 -critical-section-end end_critical_section:cs1
Пример имеет две точки входа, my_task
и reset
. my_task
вводит критический раздел через вызов begin_critical_section();
. my_task
концы, не вызывая end_critical_section
.
Одна возможная коррекция должна вызвать разблокировать функциональный end_critical_section
после инструкций в критическом разделе.
void begin_critical_section(void); void end_critical_section(void); int global_var; void reset(void) { begin_critical_section(); global_var = 0; end_critical_section(); } void my_task(void) { begin_critical_section(); global_var += 1; end_critical_section(); }
void begin_critical_section(void);
void end_critical_section(void);
int global_var;
void reset() {
begin_critical_section();
global_var=0;
end_critical_section();
}
void my_task(void) {
int index=0;
volatile int numCycles;
while(numCycles) {
begin_critical_section();
global_var ++;
if(index%10==0) {
global_var = 0;
end_critical_section();
}
index++;
}
}
В этом примере, чтобы эмулировать многозадачное поведение, задают следующие опции.
Опция | Спецификация | |
---|---|---|
Configure multitasking manually | ||
Tasks |
| |
Critical section details | Starting routine | Ending routine |
begin_critical_section | end_critical_section |
На командной строке можно использовать следующее:
polyspace-bug-finder -entry-points my_task,reset -critical-section-begin begin_critical_section:cs1 -critical-section-end end_critical_section:cs1
Пример имеет две точки входа, my_task
и reset
.
В while
цикл, my_task
вводит критический раздел через вызов begin_critical_section();
. В итерации while
цикл:
Если my_task
вводит if
ветвь условия, критический раздел заканчивается через вызов end_critical_section
.
Если my_task
не вводит if
ветвь условия и листы while
цикл, критический раздел не заканчивается. Поэтому дефект Missing unlock происходит.
Если my_task
не вводит if
ветвь условия и продолжается к следующей итерации while
цикл, блокировка функционирует begin_critical_section
называется снова. Дефект Double lock происходит.
Поскольку numCycles
volatile
переменная, это может принять любое значение. Любой из случаев выше возможен. Поэтому дефект Missing unlock и дефект Double lock появляются на вызове begin_critical_section
.
Одна возможная коррекция должна вызвать разблокировать функциональный end_critical_section
вне if
условие.
void begin_critical_section(void); void end_critical_section(void); int global_var; void reset() { begin_critical_section(); global_var=0; end_critical_section(); } void my_task(void) { int index=0; volatile int numCycles; while(numCycles) { begin_critical_section(); global_var ++; if(index%10==0) { global_var=0; } end_critical_section(); index++; } }
Другая возможная коррекция должна вызвать разблокировать функциональный end_critical_section
в каждом ветви if
условие.
void begin_critical_section(void); void end_critical_section(void); int global_var; void reset() { begin_critical_section(); global_var=0; end_critical_section(); } void my_task(void) { int index=0; volatile int numCycles; while(numCycles) { begin_critical_section(); global_var ++; if(index%10==0) { global_var=0; end_critical_section(); } else end_critical_section(); index++; } }
Двойной замок происходит когда:
Задача вызывает функцию блокировки my_lock
.
Задача вызывает my_lock
снова прежде, чем вызвать соответствие разблокировали функцию.
В многозадачном коде функция блокировки начинает критический раздел кода, и разблокировать функция заканчивает его. Когда задача task1
вызывает функцию блокировки lock
, другие задачи, вызывая lock
должен ожидать до task
вызовы соответствие разблокировали функцию. Polyspace требует, чтобы и блокировка и разблокировала функции, должен иметь форму void func(void)
.
Чтобы найти этот дефект, необходимо задать многозадачные опции перед анализом. Чтобы задать эти опции, на панели Configuration, выбирают Multitasking.
Вызов функции блокировки начинает критический раздел так, чтобы другие задачи ожидали, чтобы ввести тот же критический раздел. Если та же функция блокировки вызвана снова в критическом разделе, задача блокирует себя.
Фиксация зависит от первопричины дефекта. Дефект двойного замка часто указывает на ошибку кодирования. Возможно, вы не использовали вызов разблокировать функции, чтобы закончить предыдущий критический раздел и запустили следующий критический раздел. Возможно, вы хотели использовать различную функцию блокировки для второго критического раздела.
Идентифицируйте каждый критический раздел кода, то есть, раздел, что вы хотите быть выполненными как атомарный блок. Вызовите функцию блокировки в начале раздела. В критическом разделе убедитесь, что вы не вызываете функцию блокировки снова. В конце раздела вызовите разблокировать функцию, которая соответствует функции блокировки.
Смотрите примеры мер ниже. Чтобы избежать проблемы, можно применить практику вызова блокировки и разблокировать функции в том же модуле на том же уровне абстракции. Например, в этом примере, func
вызывает блокировку, и разблокируйте функцию на том же уровне, но func2
не делает.
void func() { my_lock(); { // ... } my_unlock(); } void func2() { { my_lock(); // ... } my_unlock(); }
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.
int global_var;
void lock(void);
void unlock(void);
void task1(void)
{
lock();
global_var += 1;
lock();
global_var += 1;
unlock();
}
void task2(void)
{
lock();
global_var += 1;
unlock();
}
В этом примере, чтобы эмулировать многозадачное поведение, необходимо задать следующие опции:
Опция | Спецификация | |
---|---|---|
Configure multitasking manually | ||
Tasks |
| |
Critical section details | Starting routine | Ending routine |
lock | unlock |
На командной строке можно использовать следующее:
polyspace-bug-finder -entry-points task1,task2 -critical-section-begin lock:cs1 -critical-section-end unlock:cs1
task1
вводит критический раздел через вызов lock();
. task1
вызовы lock
снова, прежде чем это оставляет критический раздел через вызов unlock();
.
Если вы хотите первый global_var+=1;
чтобы найтись вне критического раздела, одна возможная коррекция должна удалить первый вызов lock
. Однако, если другие задачи используют global_var
, этот код может произвести Data race
ошибка.
int global_var; void lock(void); void unlock(void); void task1(void) { global_var += 1; lock(); global_var += 1; unlock(); } void task2(void) { lock(); global_var += 1; unlock(); }
Если вы хотите первый global_var+=1;
чтобы быть в критическом разделе, одна возможная коррекция должна удалить второй вызов lock
.
int global_var; void lock(void); void unlock(void); void task1(void) { lock(); global_var += 1; global_var += 1; unlock(); } void task2(void) { lock(); global_var += 1; unlock(); }
Если вы хотите второй global_var+=1;
чтобы быть в критическом разделе, другая возможная коррекция должна добавить другой вызов unlock
.
int global_var; void lock(void); void unlock(void); void task1(void) { lock(); global_var += 1; unlock(); lock(); global_var += 1; unlock(); } void task2(void) { lock(); global_var += 1; unlock(); }
int global_var;
void lock(void);
void unlock(void);
void performOperation(void) {
lock();
global_var++;
}
void task1(void)
{
lock();
global_var += 1;
performOperation();
unlock();
}
void task2(void)
{
lock();
global_var += 1;
unlock();
}
В этом примере, чтобы эмулировать многозадачное поведение, необходимо задать следующие опции:
Опция | Спецификация | |
---|---|---|
Configure multitasking manually | ||
Tasks |
| |
Critical section details | Starting routine | Ending routine |
lock | unlock |
На командной строке можно использовать следующее:
polyspace-bug-finder -entry-points task1,task2 -critical-section-begin lock:cs1 -critical-section-end unlock:cs1
task1
вводит критический раздел через вызов lock();
. task1
вызывает функциональный performOperation
. В performOperation
, lock
называется снова даже при том, что task1
не оставил критический раздел через вызов unlock();
.
В деталях результата для дефекта вы видите последовательность продвижения инструкций к дефекту. Например, вы видите что, следуя за первой записью в критический раздел, путь к выполнению:
Вводит функциональный performOperation
.
В performOperation
, попытки ввести тот же критический раздел еще раз.
Можно кликнуть по каждому событию, чтобы перейти к соответствующей линии в исходном коде.
Одна возможная коррекция должна удалить вызов lock
в task1
.
int global_var; void lock(void); void unlock(void); void performOperation(void) { global_var++; } void task1(void) { lock(); global_var += 1; performOperation(); unlock(); } void task2(void) { lock(); global_var += 1; unlock(); }
Дважды разблокируйте, происходит когда:
Задача вызывает функцию блокировки my_lock
.
Вызовы задачи соответствие разблокировали функциональный my_unlock
.
Задача вызывает my_unlock
снова. Задача не вызывает my_lock
во второй раз между двумя вызовами my_unlock
.
В многозадачном коде функция блокировки начинает критический раздел кода, и разблокировать функция заканчивает его. Когда задача task1
вызывает функцию блокировки my_lock
, другие задачи, вызывая my_lock
должен ожидать до task1
вызовы соответствие разблокировали функцию. Polyspace требует, чтобы и блокировка и разблокировала функции, должен иметь форму void func(void)
.
Чтобы найти этот дефект, необходимо задать многозадачные опции перед анализом. Чтобы задать эти опции, на панели Configuration, выбирают Multitasking.
Двойное разблокировало дефект, может указать на ошибку кодирования. Возможно, вы хотели вызвать различное, разблокировали функцию, чтобы закончить различный критический раздел. Возможно, вы вызвали разблокировать функцию преждевременно в первый раз, когда и только второй вызов указывает на конец критического раздела.
Фиксация зависит от первопричины дефекта.
Идентифицируйте каждый критический раздел кода, то есть, раздел, что вы хотите быть выполненными как атомарный блок. Вызовите функцию блокировки в начале раздела. Только в конце раздела, вызовите разблокировать функцию, которая соответствует функции блокировки. Удалите любой другой избыточный вызов разблокировать функции.
Смотрите примеры мер ниже. Чтобы избежать проблемы, можно применить практику вызова блокировки и разблокировать функции в том же модуле на том же уровне абстракции. Например, в этом примере, func
вызывает блокировку, и разблокируйте функцию на том же уровне, но func2
не делает.
void func() { my_lock(); { // ... } my_unlock(); } void func2() { { my_lock(); // ... } my_unlock(); }
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.
int global_var;
void BEGIN_CRITICAL_SECTION(void);
void END_CRITICAL_SECTION(void);
void task1(void)
{
BEGIN_CRITICAL_SECTION();
global_var += 1;
END_CRITICAL_SECTION();
global_var += 1;
END_CRITICAL_SECTION();
}
void task2(void)
{
BEGIN_CRITICAL_SECTION();
global_var += 1;
END_CRITICAL_SECTION();
}
В этом примере, чтобы эмулировать многозадачное поведение, необходимо задать следующие опции:
Опция | Значение | |
---|---|---|
Configure multitasking manually | ||
Tasks |
| |
Critical section details | Starting routine | Ending routine |
BEGIN_CRITICAL_SECTION | END_CRITICAL_SECTION |
На командной строке можно использовать следующее:
polyspace-bug-finder -entry-points task1,task2 -critical-section-begin BEGIN_CRITICAL_SECTION:cs1 -critical-section-end END_CRITICAL_SECTION:cs1
task1
вводит критический раздел через вызов BEGIN_CRITICAL_SECTION();
. task1
оставляет критический раздел через вызов END_CRITICAL_SECTION();
. task1
вызовы END_CRITICAL_SECTION
снова без промежуточного вызова BEGIN_CRITICAL_SECTION
.
Если вы хотите второй global_var+=1;
чтобы найтись вне критического раздела, одна возможная коррекция должна удалить второй вызов END_CRITICAL_SECTION
. Однако, если другие задачи используют global_var
, этот код может произвести Data race
ошибка.
int global_var; void BEGIN_CRITICAL_SECTION(void); void END_CRITICAL_SECTION(void); void task1(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); global_var += 1; } void task2(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); }
Если вы хотите второй global_var+=1;
чтобы быть в критическом разделе, одна возможная коррекция должна удалить первый вызов END_CRITICAL_SECTION
.
int global_var; void BEGIN_CRITICAL_SECTION(void); void END_CRITICAL_SECTION(void); void task1(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; global_var += 1; END_CRITICAL_SECTION(); } void task2(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); }
Если вы хотите второй global_var+=1;
чтобы быть в критическом разделе, другая возможная коррекция должна добавить другой вызов BEGIN_CRITICAL_SECTION
.
int global_var; void BEGIN_CRITICAL_SECTION(void); void END_CRITICAL_SECTION(void); void task1(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); } void task2(void) { BEGIN_CRITICAL_SECTION(); global_var += 1; END_CRITICAL_SECTION(); }
Группа: Rec. 14. Параллелизм (CON) |
[1] Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.
ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ-МЕЛЛОН И/ИЛИ ЕГО ИНСТИТУТА ПРОГРАММНОЙ ИНЖЕНЕРИИ СОДЕРЖАЛ, ЗДЕСЬ ПРЕДОСТАВЛЯЕТСЯ НА ОСНОВЕ "ASIS". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ОПИСАЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.
Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.