Thread overview | |||||
---|---|---|---|---|---|
|
October 21, 2010 atomicOp problem | ||||
---|---|---|---|---|
| ||||
I recently read the book "the D programming language" and wanted to try out a few of the multithreaded examples pointed out in this book. I tried to write a version of the bank account example using the atomicOp from core.atomic. But when I compile it, it never finishes, it just gets stuck in a endless loop inside atomic.d I think.
Here is the code:
import std.stdio;
import std.concurrency;
enum Messages {
GO
}
shared class Account {
private float amount = 0;
float getAmount() const {
return amount;
}
void change(float 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);
}
void main(string[] args)
{
bank = new Account();
spawn(&otherThread,thisTid);
receiveOnly!(Messages)();
for(int i=0;i<1000;i++)
bank.change(+100);
writefln("Program finished. Amount is %s",bank.getAmount());
}
If you could please point out what I did wrong I would be very glad. If I did not do anything wrong, I don't quite understand whats the exact problem because the code inside atomic.d looks good (at least at my level of understanding)
--
Kind Regards
Benjamin Thaut
|
October 21, 2010 Re: atomicOp problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | Benjamin Thaut <code@benjamin-thaut.de> wrote: > I recently read the book "the D programming language" and wanted to try out a few of the multithreaded examples pointed out in this book. I tried to write a version of the bank account example using the atomicOp from core.atomic. But when I compile it, it never finishes, it just gets stuck in a endless loop inside atomic.d I think. [...] > If you could please point out what I did wrong I would be very glad. If I did not do anything wrong, I don't quite understand whats the exact problem because the code inside atomic.d looks good (at least at my level of understanding) Are you sure it's endless? IIRC atomic increment on x86 has some fairly severe performance considerations and you are setting it ip for maximal contention. Try running it for 100 cycles and see if that works. OTOH I'm no expert so I could be totally off base. > -- > Kind Regards > Benjamin Thaut |
October 21, 2010 Re: atomicOp problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut |
Interesting!
I get the same result, ie an infinite loop, with the CPU at 100%
Some things I noticed:
- Changing the for-loops to 100 or 10 doesn't help.
- Changing the atomicOp from "+=" to just "+" makes it work (although the account doesn't get changed)
- Adding a Thread.sleep(1000) in one of the for-loops, before the call to atomic-op, makes it all work with "+=" as well
By looking at the code in atomic.d it looks the "+="-operator ends up here:
// L#131..:
T get, set;
do
{
get = set = atomicLoad!(msync.raw)( val );
mixin( "set " ~ op ~ " mod;" );
} while( !cas( &val, get, set ) );
return set;
And I suppose the cas()-function never returns true?
I don't know how atomic is supposed to work, so I'm not sure if it's a bug or not. I'm no expert with D, or threading for that matter, so I don't know. (I'm just an expert guesser : )
I guess bug!
BR
/HF
Benjamin Thaut Wrote:
> I recently read the book "the D programming language" and wanted to try
> out a few of the multithreaded examples pointed out in this book. I
> tried to write a version of the bank account example using the atomicOp
> from core.atomic. But when I compile it, it never finishes, it just gets
> stuck in a endless loop inside atomic.d I think.
> Here is the code:
>
> import std.stdio;
> import std.concurrency;
>
> enum Messages {
> GO
> }
>
> shared class Account {
> private float amount = 0;
>
> float getAmount() const {
> return amount;
> }
>
> void change(float 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);
> }
>
> void main(string[] args)
> {
> bank = new Account();
> spawn(&otherThread,thisTid);
> receiveOnly!(Messages)();
> for(int i=0;i<1000;i++)
> bank.change(+100);
> writefln("Program finished. Amount is %s",bank.getAmount());
> }
>
> If you could please point out what I did wrong I would be very glad. If I did not do anything wrong, I don't quite understand whats the exact problem because the code inside atomic.d looks good (at least at my level of understanding)
>
> --
> Kind Regards
> Benjamin Thaut
|
Copyright © 1999-2021 by the D Language Foundation