std.concurrency bug?
Charles Hixson via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue May 20 17:24:45 PDT 2014
On Tuesday, May 20, 2014 11:42:48 AM Ali Çehreli via Digitalmars-d-learn
wrote:
> On 05/20/2014 11:38 AM, Charles Hixson via Digitalmars-d-learn wrote:
> > Is it a bug that an immutable struct cannot be sent to a thread? (It
> > compiles without problem if I make all elements mutable.)
>
> Does the struct have any mutable indirection? Then it is illegal.
> Otherwise, can you demonstrate with minimal code please?
>
> Ali
Nearly a minimal example. If "void sendMsg (Msg m){...}" is removed there's
not compilation error.
import std.array;
import std.concurrency;
import std.datetime;
import std.format;
import std.stdio;
import std.stdint;
import std.string;
import std.variant;
enum numCThreads = 4;
class UnexpectedMessage : Exception { this (string s) { super (s);
} }
enum Act {create, activate, deactivate, wait, read, reset, save, done}
string toString(E)(E value) if (is(E == enum))
{ foreach (s; __traits(allMembers, E))
{ if (value == mixin("E." ~ s) ) return s; }
return null;
} // string toString (... for enum
/** This is the only message that one cell sends to another. */
struct Msg
{ /** The cell id# of the sender of the message. */
immutable uint64_t from;
/** The cell id# of the recipient of the message. */
immutable uint64_t to;
/** The kind of action the message is impelling. */
immutable Act act;
/** The tick on which the message was accepted for transmission.
* This is set by std.datetime.Clock.currStdTime() */
immutable long tick;
/** Distance between cells. Not currently well defined except in
* the case of two words, in which case it is the number of words of
* separation, where adjacent is 1. */
immutable float dist;
/** Not currently well defined. */
immutable int value;
this (uint64_t from, uint64_t to, Act act, float dist, int value)
{ this.from = from;
this.to = to;
this.act = act;
this.tick = Clock.currStdTime;
this.dist = dist;
this.value = value;
}
}
void cellThread(size_t ndx, shared(Tid)[] cThreads)
{ /** Unprocessed message queue, indexed by cell id#. */
Msg msgs[uint64_t][];
bool done = false;
//TODO load the cells into the thread
/** Receive all messages in the mailbox. Wait 2 ns for response. */
while (!done && receiveTimeout (0.seconds,
(Msg m)
{ if (m.to in msgs)
{ msgs[m.to] ~= m; }
else
{ msgs[m.to] = [m]; }
},
(Act act)
{ switch (act)
{ case Act.done: // end cell processing
done = true;
break;
default:
auto s = format (
"Error in thread %s: received message
Act.%s",
ndx, act);
writefln (s);
throw new UnexpectedMessage(s);
} // switch (act)
} //(Act act)
) )
{
} // while (!done && receiveTimeout
void sendMsg (Msg m)
{ assert (m.to > 0);
assert (m.to < lastId);
int ndx = m.to % numCThreads;
Tid ct = cast(Tid)cThreads[ndx];
ct.send(m);
}
} // void cellThread()
void main()
{ auto cellTids = new shared(Tid)[numCThreads];
foreach (id; 0 .. numCThreads)
{ auto cThread = spawn(&cellThread, id, cellTids);
cellTids[id] = cast(shared(Tid))cThread;
}
foreach (cThread; cellTids)
{ Tid ct = cast(Tid)cThread;
ct.send(Act.done);
}
}
More information about the Digitalmars-d-learn
mailing list