On Sat, 23 Oct 2010 15:50:30 -0400, Sean Kelly <s...@invisibleduck.org> wrote:

Benjamin Thaut <c...@benjamin-thaut.de> wrote:
Am 23.10.2010 14:52, schrieb dsimcha:
== Quote from Benjamin Thaut (c...@benjamin-thaut.de)'s article
The following testcase (when executed on dual core at least) results
> > in
a endless loop inside atomicOp.
import std.stdio;
import std.concurrency;
enum Messages {
        GO,
        END
}
shared class Account {
        private double amount = 0;
        double getAmount() const {
                return amount;
        }
        void change(double change){
                atomicOp!"+="(amount,change);
        }
}
shared Account bank = null;
void otherThread(Tid father){
        send(father,Messages.GO);
        for(int i=0;i<1000;i++)
                bank.change(-100);
        send(father,Messages.END);
}
void main(string[] args)
{
        bank = new Account();
        spawn(&otherThread,thisTid);
        receiveOnly!(Messages)();
        for(int i=0;i<1000;i++)
                bank.change(+100);
        receiveOnly!(Messages)();
        writefln("Program finished. Amount is %s",bank.getAmount());
}
Is this a bug, or am I doing something wrong here?
If it is a bug it is kind of critical because people which are
> > reading
the "the D programming language" book won't be happy to find out
> > that
some of the given examples do not work yet.

http://d.puremagic.com/issues/show_bug.cgi?id=4782

Basically, atomicLoad (which atomicOp uses) always returns in ALU
> registers.
Floating point numbers need to be returned in floating point
> registers.
Therefore, a NaN always gets returned from atomicLoad!double, and a
> NaN isn't
equal to anything.

So shouldn't there be a static assert to prevent one from using
atomicOp with floats and doubles? Or should atomicLoad be implemented
to support floats and doubles?

The former in the short term and the latter in the long term.

Well, here's the assembler to load a value onto the FP stack:
float  __int2float  (ref int  x) { asm { fld float  ptr [EAX]; } }
double __long2double(ref long x) { asm { fld double ptr [EAX]; } }

Unfortunately, direct loading from a register doesn't seem to be supported. So writing wrapper code which uses a union would be almost as fast. I know there is an SSE instruction to load directly from registers, but we can't assume SSE support.

Reply via email to