I will add hints here as I find them. Currently there is not a lot here.
Some ideas on:
This has the disadvantage that the unpacking of globals will occur even if the new process shares address space with the "main" process. This can be avoided in C++-with-Ease though use of the marshalling mechanism. An object will only be marshalled if it is passed to another address space, otherwise the copy constructor or assignment operator will be used. Thus, by having an empty structure as the "global" object and having marshalling operaters that pack and unpack all required globals we only do the work when it is necessary.
int global1, global2; struct Global {}; mStream& operator << (mStream& s, Global const &x) { s << global1 << global2; // ... return s; } umStream& operator >> (umStream& s, Global &x) { s >> global1 >> global2; // ... return s; } //... @process func(@share<Global> g) { Global junk; @read(g, junk); // ... } int eMain(int, char**) { @share<Global> globals; Global junk; @put(globals, junk); @subordinate func(globals); // ... }
One way to create a pipeline is to create a number of contexts (say one per process) prior to creating the processes and then passing the contexts in as parameters. To improve efficiency (potentially) the destination process should @own the context.
For example (in C-with-Ease) :
@process proc(@share @stream in, @share @stream out) { int i; @own(in); @get(in, i); i++; @put(out, i); } void eMain(int, char **) { @share @stream x[20]; int i,j; for (i=0;i<20;i++) @init(x[i]); @subordinate (j @for 19) proc(x[i], x[i+1]); @write(x[0], i); @get(x[19], j); printf("Sent %d, got %d back\n",i,j); }