XC - Common Pitfalls

Archived XCore tutorials.
User avatar
skoe
Experienced Member
Posts: 94
Joined: Tue Apr 27, 2010 10:55 pm

XC - Common Pitfalls

Post by skoe »

Every programming language and every platform has its pitfalls. Lets collect the stuff which ate up your time here. Please only post things which are helpful to others and please add a small sample to make it comprehensible. If applicable, write the error message here so it can be found by the search function.

Asynchronous channel usage

Normal channels can't be used asynchronously, i.e. both sides must not send at the same time. They do a handshake which will fail with ET_ILLEGAL_RESOURCE if you try.

Streaming channels don't do this, so they can be used in this way. But when using streaming channels it's your responsibility to keep track of the data sizes sent through the channel.

Code: Select all

#include <stdio.h> 

int main(void) { 
    chan c;    // <= will fail
    // streaming chan c;   // <= works
    int a, b, i, j;
    a = 1;
    b = 2;
    par
    {
        {
            c <: a;
            c :> i;
        }
        {
            c <: b;
            c :> j;
        }
    }
    printf("%d %d\n", i, j);
    return 0;
}
User avatar
paul
XCore Addict
Posts: 169
Joined: Fri Jan 08, 2010 12:13 am

Post by paul »

Streaming channels don't do this, so they can be used in this way. But when using streaming channels it's your responsibility to keep track of the data sizes sent through the channel.
What do you mean by this?

The only reason you can use the channel in the way you have done is because of the small buffer (8 bytes) that channel has. If you try and do the following example you will get a deadlock because the channel buffer will be full- and it won't give you an exception, just stall.

Simple pseudo XC example:

Code: Select all

par {
        { c <: i; c <: j; c <: k; c :> i; c:> j; c:> k;}
        { c <: e; c <: f; c <: g; c :> e; c:> f; c:> g;}
}
Cheers,
Paul

On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.
User avatar
skoe
Experienced Member
Posts: 94
Joined: Tue Apr 27, 2010 10:55 pm

Post by skoe »

What do you mean by this?
I meant the additional handshake which is done using STOP control tokens.

You are right, the deadlock you describe is very important to be mentioned here because it may be difficult to track it down. When the channels are used in a bi-directional way it's important to make sure that the implementation doesn't write too much data without being able to input anything.

Just an addition: This can also happen if two channels are in use, one for each direction:

Code: Select all

par {
    { c1 <: a; c1 <: a; c2 :> i; c2 :> i; }
    { c2 <: b; c2 <: b; c1 :> j; c1 :> j; }
}
This code will stall when normal channels are used. It doesn't stall with streaming channels because two int values fit into the 8 byte buffer. But when e.g. three int values are sent in a line also streaming channels will stall here.

To avoid this one could use a request-response model (which can be realized with both types of channels) or make sure that the processing of the receiver is faster than the input of the next value.

Regards,
Thomas
User avatar
nassim
Experienced Member
Posts: 112
Joined: Sun Sep 05, 2010 3:39 pm

Post by nassim »

Hi all

thanks for this tuto and it's very useful for any beginner

thanks
User avatar
aleonard
Member
Posts: 15
Joined: Thu Sep 16, 2010 8:19 pm

Post by aleonard »

I spent some time on this same issue. In my case the threads would just stall and not throw a runtime exception. I found this explanation from Woody here: http://www.xcore.com/forum/viewtopic.ph ... one+thread
that helped me understand what was going on :
When one thread performs a <: output operation on a channel and another thread performs a :> input on the same channel the two threads become synchronized in time at that point. This will often mean that one of the two threads will pause until the time that the other thread reaches the point in it's code where it either reads or write the data.

Streamed channels do not do this: when the :> output occurs, that thread does not pause, but continues executing code, and the data is stored in the receiving channel end's 8 byte input buffer. If that thread then issues another :> output that will also be stored in the input buffer and the code should continue to execute. If a third :> output is issued, the tx thread will pause.

Transactions over an unstreamed channel still synchronize, but do not have much of an overhead to synchronize.