Получите и выпустите примитивы синхронизации в том же модуле на том же уровне абстракции
Отсутствие блокировки происходит, когда задача вызывает разблокировать функцию прежде, чем вызвать соответствующую функцию блокировки.
В многозадачном коде функция блокировки начинает критический раздел кода, и разблокировать функция заканчивает его. Когда задача, 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. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.