There isn't enough information to answer this definitively.
If either of the CPUs decide to cache the memory at *int_pointer
, this will always fail and your extra code will not fix any race condition.
Assuming both CPUs know that memory at *int_pointer
is uncacheable, AND that location *int_pointer
is aligned on a 4-byte/32-bit boundary AND the CPU on the PCI card has a 32 bit memory interface, AND the pointer is declared as a pointer to volatile
AND both your C compilers implement volatile correctly, THEN it is likely that the updates will be atomic.
If any of the above conditions are not met, the result will be unpredictable and your "race detection" code is not likely to work.
Edited to explain why volatile
is needed:
Here is your race condition code compiled to MIPS assembler with -O4
and no volatile
qualifier. (I used MIPS because the generated code is easier to read than x86 code):
int nonvol(int *ip) {
int number = *ip;
while (*ip != number) {
number = *ip;
}
return number;
}
Disassembly output:
00000000 <nonvol>:
0: 8c820000 lw v0,0(a0)
4: 03e00008 jr ra
The compiler has optimized the while
loop away since it knows that *ip
cannot change.
Here's what happens with volatile
and the same compiler options:
int vol(volatile int *ip) {
int number = *ip;
while (*ip != number) {
number = *ip;
}
return number;
}
Disassembly output:
00000008 <vol>:
8: 8c820000 lw v0,0(a0)
c: 8c830000 lw v1,0(a0)
10: 1443fffd bne v0,v1,8 <vol>
14: 00000000 nop
18: 03e00008 jr ra
Now the while
loop is not optimized away because using volatile
has told the compiler that *ip
can change at any time.