Still more doubles

(earlier posts: part 1 and part 2)

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):

    0x1.e3b80001e3b8p+14     0x1.e3b80001f174p+14             -0x1.b78p-23
    ^^ expected value        ^^^ read value                   ^^ difference
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'.

Files currently attached to this page:

doubletest-bad.c832 bytes
doubletest.c727 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