...
In the above piece of code, the value of flag
is used to determine if the critical section can be executed or not. flag
is not declared as being of type volatile
and so may be cached in registers. Before the value in the register is written to memory, another thread might be scheduled to run and so may end up reading stale data.
Noncompliant Code Example
The following code uses flag
as a synchronization primitive but this time declared as type volatile
Code Block | ||
---|---|---|
| ||
volatile bool flag = false;
void test(){
while (!flag){
sleep(1000);
}
}
void wakeup(){
flag = true;
}
void debit(int amount){
test();
account_balance -= amount;
}
|
Declaring flag
as volatile solves the problem of reading stale data, but still does not provide atomicity guarantees needed for synchronization primitives to work correctly. The volatile
keyword does not promise to provide the guarantees needed for synchronization primitives.
...