Re: std.concurrency bug?

2014-05-22 Thread Sean Kelly via Digitalmars-d-learn

On Wednesday, 21 May 2014 at 20:19:32 UTC, Ali Çehreli wrote:


I think this is a known issue with immutable and Variant, which 
std.concurrency uses for unknown messages. This looks related:


  https://issues.dlang.org/show_bug.cgi?id=5538


std.concurrency actually uses Variant as the transport mechanism 
for all messages, and this is most likely the cause of your 
problem.  If this is just to make a class pass type checking for 
transport, casting to shared is probably a better bet.  The real 
solution is to make std.concurrency effectively allow uniquely 
referenced classes to be transferred, but that's a bit farther 
out.


Re: std.concurrency bug?

2014-05-21 Thread Ali Çehreli via Digitalmars-d-learn

On 05/20/2014 05:24 PM, Charles Hixson via Digitalmars-d-learn wrote:

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

Further reduced:

import std.concurrency;

struct S
{
immutable int i;
}

void foo()
{}

void main()
{
auto f = spawn(foo);

auto s = S();
f.send(s);
}

I think this is a known issue with immutable and Variant, which 
std.concurrency uses for unknown messages. This looks related:


  https://issues.dlang.org/show_bug.cgi?id=5538

Ali



Re: std.concurrency bug?

2014-05-21 Thread Charles Hixson via Digitalmars-d-learn
On Wednesday, May 21, 2014 01:19:32 PM Ali Çehreli via Digitalmars-d-learn 
wrote:
 On 05/20/2014 05:24 PM, Charles Hixson via Digitalmars-d-learn wrote:
   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.)
 
 Further reduced:
 
 import std.concurrency;
 
 struct S
 {
  immutable int i;
 }
 
 void foo()
 {}
 
 void main()
 {
  auto f = spawn(foo);
 
  auto s = S();
  f.send(s);
 }
 
 I think this is a known issue with immutable and Variant, which
 std.concurrency uses for unknown messages. This looks related:
 
https://issues.dlang.org/show_bug.cgi?id=5538
 
 Ali
Thanks.  Fortunately, I don't really need for messages to be immutable, I just 
thought it would be safer (as in avoiding the possibility of making a 
mistake).  They're stucts, and I never pass a pointer, just the struct.  Being 
immutable would allow me to guarantee that certain logic errors couldn't be 
committed is all.



std.concurrency bug?

2014-05-20 Thread Charles Hixson via Digitalmars-d-learn
Is it a bug that an immutable struct cannot be sent to a thread?  (It compiles 
without problem if I make all elements mutable.)


Re: std.concurrency bug?

2014-05-20 Thread Ali Çehreli via Digitalmars-d-learn

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



Re: std.concurrency bug?

2014-05-20 Thread Charles Hixson via Digitalmars-d-learn
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
Nope.  Here it is (with the immutable tags removed):
/** This is the only message that one cell sends to another.*/
struct Msg
{   /** The cell id# of the sender of the message.  */
uint64_tfrom;
/** The cell id# of the recipient of the message.   */
uint64_tto;
/** The kind of action the message is impelling.*/
Act act;
/** The tick on which the message was accepted for transmission.
 * This is set by std.datetime.Clock.currStdTime()  */
longtick;
/** 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. */
float   dist;
/** Not currently well defined. */
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;
}
}




Re: std.concurrency bug?

2014-05-20 Thread Charles Hixson via Digitalmars-d-learn
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  voidsendMsg (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;

enumnumCThreads =   4;


class   UnexpectedMessage   :   Exception { this (string s) { super 
(s); 
} }

enumAct {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_tfrom;
/** The cell id# of the recipient of the message.   */
immutable   uint64_tto;
/** 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   longtick;
/** 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;
}
}

voidcellThread(size_t ndx, shared(Tid)[] cThreads)
{   /** Unprocessed message queue, indexed by cell id#. */
Msg msgs[uint64_t][];
booldone=   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)
{   caseAct.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

voidsendMsg (Msg m)
{   assert (m.to  0);
assert (m.to  lastId);
int ndx =   m.to % numCThreads;
Tid ct  =   cast(Tid)cThreads[ndx];
ct.send(m);
}
}   //  voidcellThread()


voidmain()
{   autocellTids=   new shared(Tid)[numCThreads];
foreach (id; 0 .. numCThreads)
{   autocThread =   spawn(cellThread, id, cellTids);
cellTids[id]=   cast(shared(Tid))cThread;
}
foreach (cThread; cellTids)
{   Tid ct  =   cast(Tid)cThread;
ct.send(Act.done);
}
}