Working & talking at the same time?

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am
Contact:

Working & talking at the same time?

Post by Interactive_Matter »

Hi,

I got an XC beginners problem:

I have a thread which is quite actively pumping out values through ports the whole time. The values are stored in an array. So it just pumps out the array over and over again (very simplified view).

On the other hand I must be able to write to that array. It would be best if it is done at specified events (e.g. after the array has been pumped out completely), but for starters it does not matter.

Now I got trouble figuring out to read the channel end to get new data and still pump out the array.

If I simply read the pumping stops until I got some data - not what I want

If I use streams the pumping block if nobody updates the data - also not what I want.

I have some events I am waiting for. The I can also try to wait for the time to pas or new data. If new data arrvies I do not wait for the time to pass any longer. But waiting after either waiting or reading should work. like

Code: Select all

this:
switch {
     case channel :> c;
     case t when timerafter(wait_time) :> void;
}
//ensure that the timer has passed
t when timerafter(wait_time) :>void


But that looks a bit cumbersome to me

Is there an easier way?

Thanks

Marcus


User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am
Contact:

Post by segher »

You can write the data array from a different thread (on the same core).
You can have that thread listen to a channel, if you want.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

Alternatively if you cannot afford a thread or are worried about sharing an array across threads you could use a select statement whose cases could be channel receives (for array data updates), timeouts or the default pumping ports. The select would be wrapped in a infinite loop.
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am
Contact:

Post by Interactive_Matter »

segher wrote:You can write the data array from a different thread (on the same core).
You can have that thread listen to a channel, if you want.
That is what I tried to do but the compiler told me that this violates the disjointness rules since two threads are accessing the array. Is it neccessary that one thread only has a 'const' reference to that array?
Folknology wrote:Alternatively if you cannot afford a thread or are worried about sharing an array across threads you could use a select statement whose cases could be channel receives (for array data updates), timeouts or the default pumping ports. The select would be wrapped in a infinite loop.
Yes I can afford the thread, but your approach is very interesting since I can control when the communication occurs.
But the longer I think about it the more I come to the conclusion hat it probably will not work in my case (or I did notunderstand it good enough):
I am pumping out serial data bitwise. So I have to wait for the single bits to synchronize - after I have pumped out the bits I have to pull a latch line high and wait a specified time.
The latch bit is quite a good point to check if data is availlaible.
If I use a select statement here I either input data or pull the latch line high or wait. But In theory I want to pull the line high and read all data that is available at this point.
This would bring me back to my original code:
select statement with either data reading or timeout wrapped in a while loop until the timeout has been realy reached?
Or am I just to blind and stubborn?

Thanks for your help!
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

Sure a small state machine combined, but make sure you use 'select' not 'switch' ;-)

regards
Al
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am
Contact:

Post by Interactive_Matter »

Folknology wrote:Sure a small state machine combined, but make sure you use 'select' not 'switch' ;-)

regards
Al
OK, sounds like a way to go. So my final verdict is that communication needs a lot of manual work, but that is partly ok (still have to find a way to define 'channel protocols' for complex data formats more easily).


But
segher wrote:You can write the data array from a different thread (on the same core).
You can have that thread listen to a channel, if you want.
is still very interesting - so when am I allowed to write to to variables/arrays from two different threads. The Programming XC Handbook states that it is'nt? But in there is a part where is a description with const references are OK and that puzzles me a bit.
User avatar
bsmithyman
Experienced Member
Posts: 126
Joined: Fri Feb 12, 2010 10:31 pm
Contact:

Post by bsmithyman »

Interactive_Matter wrote:is still very interesting - so when am I allowed to write to to variables/arrays from two different threads. The Programming XC Handbook states that it is'nt? But in there is a part where is a description with const references are OK and that puzzles me a bit.
Hi Marcus,

You can't use shared memory in XC without some tricks, but it's perfectly possible to do it in C; this is a restriction from the XC language, not from the hardware. Also, it's possible (or was possible) to do it using arrays in XC since they're implemented by pointers, but this is taking advantage of an oversight in the disjointness rules that is not guaranteed to exist in the long term. It's also possible to use inline assembler to do the same thing, but the C approach is probably simplest.

Cheers,
Brendan
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am
Contact:

Post by segher »

Interactive_Matter wrote:is still very interesting - so when am I allowed to write to to variables/arrays from two different threads. The Programming XC Handbook states that it is'nt? But in there is a part where is a description with const references are OK and that puzzles me a bit.
I never suggested writing from two threads. One thread writes, the other only reads.


bsmithyman wrote:You can't use shared memory in XC without some tricks
I did this:

Code: Select all

static char buf[256];
static unsigned buf_head = 0;
static unsigned buf_tail = 0;

static void bufferin(chanend ch)
{
        for (;;) {
                unsigned x;

                ch :> x;
                buf[buf_head++ % 256] = x;
        }
}

static void some_bufferout(chanend ch)
{
        while (buf_tail != buf_head)
                ch <: (unsigned)buf[buf_tail++ % 256];
}
(and I run bufferin() on a thread of its own).

I use this code for debug output, it's a circular buffer _without overflow checking_, so
don't reuse this as-is unless you know what you're doing :-)

I don't see any tricks in here.
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am
Contact:

Post by Interactive_Matter »

bsmithyman wrote:
Interactive_Matter wrote:is still very interesting - so when am I allowed to write to to variables/arrays from two different threads. The Programming XC Handbook states that it is'nt? But in there is a part where is a description with const references are OK and that puzzles me a bit.
Hi Marcus,

You can't use shared memory in XC without some tricks, but it's perfectly possible to do it in C; this is a restriction from the XC language, not from the hardware. Also, it's possible (or was possible) to do it using arrays in XC since they're implemented by pointers, but this is taking advantage of an oversight in the disjointness rules that is not guaranteed to exist in the long term. It's also possible to use inline assembler to do the same thing, but the C approach is probably simplest.

Cheers,
Brendan
This explains a lot.
Since I always asked myself what to do with xc - and your post seems like using for low level stuff, while using C/C++ for higher level wiring seems like a good way to control complexity and reuse code that exists elsewhere.
segher wrote:I never suggested writing from two threads. One thread writes, the other only reads.
+1 -you should know very well what you are doing if you are writing concurrently. I still miss 'classical' synchronization methods like mutexes or synchronizations. But perhaps you don't need it anymore - lack of experience.

segher wrote:
bsmithyman wrote:You can't use shared memory in XC without some tricks
I did this:

[...]

I don't see any tricks in here.
Hm, that looks quite similar to what I did - my code reads the array indizes from a channel - perhaps that is the point where the linker decides that I cannot do it.

Does anybody know in which defined circumstances one thread can read a variable/array while another thread writes to it?

Thanks for your help! Got a lot of insight

Marcus
Post Reply