Extend Data Race Checkers to Atomic Operations
A data race might occur when multiple threads perform concurrent operations on a shared
variable. When the operations are executed in one machine instruction, they are atomic. For
instance, reading a shared variable of type char
might take a single
machine instruction. Such atomic operations are can be performed concurrently without
triggering a data race. By default, Polyspace® Bug Finder assumes that certain operations are atomic and excludes them from
data race checks. See Define Atomic Operations in Multitasking Code.
The Polyspace assumptions about the atomic nature of operations might not apply to your environment. If you are unsure whether an operation is atomic in your environment, extend the data race checkers to include these operations.
Identify Need for Extending Checker
Operations that take more than one machine cycle to execute are nonatomic operations. For instance, consider this operation:
MYREG = (u32dma0_chbit << 8UL) | u32dma0_chbit;
Operations that take a single machine instruction to execute are assumed to be atomic. See Define Atomic Operations in Multitasking Code.
Because different machines have different word size, the Polyspace assumptions about the atomic nature of operations might not apply to your environment. For instance, consider the operation:
long long var = 0;
long long
object is less than or equal to the word
size, this operation is atomic. In target hardware where the size of a long
long
object is greater than the word size, this operation is not atomic.
For instance, the preceding operation is atomic when -target
is
x86_64
, but not atomic when -target
is
i386
. If you are not sure whether the code executes in a
x86_64
machine or in an i386
machine, extend
the data race checker to include such operations.Extend Checker
To include the assumed atomic operations when checking for data race violations,
specify the option Detect Data Race
in Atomic Operations (-detect-atomic-data-race)
. Consider this
code:
#include<stdio.h> long var; void begin_critical_section(void); void end_critical_section(void); void task1(void) { var = 1; } void task2(void) { int local_var; local_var = var; printf("%d", local_var); } void task3(void) { begin_critical_section(); /* Operations in task3 */ end_critical_section(); }
var=1;
in task
task1
executes concurrently with the read operation
local_var=var;
in task task2
. By default,
Polyspace assumes that the target processor is i386
, where these
operations occur within a single machine instruction. These operations are excluded from
a data race check.Data race might still occur in these operations when the target processor is different
from i386
. To detect possible data races in this code, specify the
option Detect Data Race
in Atomic Operations (-detect-atomic-data-race)
. At the command line,
use this command:
Windows:
polyspace-bug-finder -checkers data_race -lang cpp ^ -entry-points task1,task2,task3 ^ -critical-section-begin begin_critical_section:CS1 ^ -critical-section-end end_critical_section:CS1 ^ -detect-atomic-data-race
Linux:
polyspace-bug-finder -checkers data_race -lang cpp \ -entry-points task1,task2,task3 \ -critical-section-begin begin_critical_section:CS1 \ -critical-section-end end_critical_section:CS1 \ -detect-atomic-data-race
After specifying the option
-detect-atomic-data-race
, Polyspace flags the variablevar
.
Checkers That Can Be Extended
The concurrency defect checkers that you can extend in this way are: