The test I wrote earlier to run inside hal has one main flaw: the fatal window (if there is one) will only be seen when the fast thread interrupts the slow thread during the correct processor cycle; this won't necessarily happen very often!
So I crafted a threaded userspace program that "busy loops", one thread doing the 'update' and one thread doing the 'check'. On a dual-core machine, the correct program will run for as long as I let it. If I change the compiler flags (e.g., to -mtune=i386) or change the program to not 8-byte-align the shared variable, I quickly see failures---typically, within a few seconds.
(On a single-core machine, I see the "two movl" case quickly, but the "misaligned fldl" case not at all---as far as I can tell from architecture references, the fld and fst instructions are never interrupted, so on single-core systems this may in fact not be a problem)
Correct program: gcc -Os doubletest.c -pthread
Incorrect program: gcc -mtune=i386 doubletest.c -pthread
Incorrect program: gcc -Os doubletest-bad.c -pthread
When the program detects a problem, it prints a line like the following and exits (when the program runs forever, that means everything is OK):
Here, 'check' read a number whose integer part was 0x1e3b8. 32 bits into the fraction part should be another 0x1e3b8. Instead, the fractional part has 0x1f174. This mismatch was due to the "two movl" code sequence to read the value in 'check'.0x1.e3b80001e3b8p+14 0x1.e3b80001f174p+14 -0x1.b78p-23 ^^ expected value ^^^ read value ^^ difference
Files currently attached to this page:
doubletest-bad.c | 832 bytes |
doubletest.c | 727 bytes |
(originally posted on the AXIS blog)
Entry first conceived on 3 November 2008, 2:49 UTC, last modified on 15 January 2012, 3:46 UTC
Website Copyright © 2004-2024 Jeff Epler