What is meant by "channel buffering being full"

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
wibauxl
Active Member
Posts: 35
Joined: Mon Dec 14, 2009 4:40 pm

What is meant by "channel buffering being full"

Post by wibauxl »

In the transaction and streaming channel documentation of XC, there is a mention of a "channel buffering capacity", and no mention of size.
Can I set this buffer size somewhere?
Can I test if there is data pending in a stream without consuming the data?

Thanks,


User avatar
paul
XCore Addict
Posts: 169
Joined: Fri Jan 08, 2010 12:13 am

Post by paul »

In the transaction and streaming channel documentation of XC, there is a mention of a "channel buffering capacity", and no mention of size.
Can I set this buffer size somewhere?
The buffers aren't customizable on channels. There is a buffer of 2 words (so 2 integers). After that is full outputs into the channel will block.
Can I test if there is data pending in a stream without consuming the data?
Only if it is a control token by using the testct( chan ) function. This is documented in the library documentation that comes with the tools (see $(TOOLS ROOT)/DesktopTools/<version>/doc/libs/html/index.html) - see particularly the xs1.h.
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
wibauxl
Active Member
Posts: 35
Joined: Mon Dec 14, 2009 4:40 pm

Post by wibauxl »

Thanks Paul, this is very useful information. It ought to be in XC manual somewhere...
I did not find the info easily.

In fact, I need to pass data from a camera thread to a displaying thread.
The displaying thread needs only to receive new data only when it has completed the display.
How can I do this?
If I use a channel in first thread to second thread and second thread is not finished,
first one will block and this is not OK in my application.
This might be a use for a streaming channel, but my data is about 200 words.

Code: Select all

int main() {
chan readyC, dataC; 
   par {
      T1(readyC, dataC);
      T2(dataC, readyC);
   }
}

void T1(chanend readyIn, chanend dataOut) {
   unsigned value;
   par {
      while (1) {
         value++;
         usDelay(20);
      };
      while (1) {
         readyIn :> unsigned;
         dataOut <: value;
      };
}

void T2(chanend dataIn, chanend readyOut) {
   unsigned value;
   while (1) {
      readyOut <: 1;
      dataIn :> value;
      usDelay(100);
   }
}
But it says that I am breaking the par disjointness rules on variables.
Yet while T1 part 1 modifies value, T1 part 2 only reads it.
How can I resolve that?

Thanks
User avatar
paul
XCore Addict
Posts: 169
Joined: Fri Jan 08, 2010 12:13 am

Post by paul »

In XC disjointness must be complete (both reading and writing). If you really want to use shared memory then its best to move to C and just call functions to do the channel communications.

Your basic problem is disconnecting a producer and consumer that aren't necessarily in sync. This is where buffers are useful. For something like camera I would have something along the lines of this:

camera thread -> buffer thread -> display thread

If you are feeling brave (and can meet your cameras timing requirements) you might be able combine the camera & buffer thread tasks into one thread.

Also, just to make you aware that channels are bidirectional, so you should be able to the the control and data channels in a single channel.
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
wibauxl
Active Member
Posts: 35
Joined: Mon Dec 14, 2009 4:40 pm

Post by wibauxl »

paul wrote:Your basic problem is disconnecting a producer and consumer that aren't necessarily in sync. This is where buffers are useful. For something like camera I would have something along the lines of this:

camera thread -> buffer thread -> display thread
This is exactly what I want to do, but I don't see how:

Code: Select all

par {
   T1(c1)
   T2(c1, c2)
   T3(c2)
}
Only if c2 is not read by T3, it will block T2, which will block T1...
There is something I don't understand in this!
Could you help me with a few lines of pseudo code or point me to the right place in the documentation?

Thanks
paul wrote:Also, just to make you aware that channels are bidirectional, so you should be able to the the control and data channels in a single channel.
I did not realise that. Not read the documentation enough!
Are directions completely independant? meaning if T1 does not read c1, will it prevent T1 writing to c1 if T2 reads it?
User avatar
wibauxl
Active Member
Posts: 35
Joined: Mon Dec 14, 2009 4:40 pm

Post by wibauxl »

Only if it is a control token by using the testct( chan ) function.
The issue I have is that this function is blocking the thread if there is no data in the channel...
I will move to C as I can't find any way of testing if data is available in the channel.

It should be possible in XC to read a channel status: full, empty as this state must be available on the hardware..
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

I think you do this with a "select" in XC.

If the channel read case is not ready it will run another arm of select which could be nothing.
User avatar
wibauxl
Active Member
Posts: 35
Joined: Mon Dec 14, 2009 4:40 pm

Post by wibauxl »

Heater wrote:I think you do this with a "select" in XC.
I tried:

Code: Select all

select {
   case t when timerafter(time) >: void:
      // do the camera read, store in buffer
      break;
   case requestingChannelEnd :> unsigned:
      // do the send to requestingChannelEnd
      break;
}
but somehow, the channel reading won't act as a proper select case (probably because unblocking a channel is not considered an event...).

I have solved the situation by a thread safe buffer written in C, called by both branches of my function. Not too clean though because I use a 'par' statement in my function but write and read to a common place in RAM, so both threads of the 'par' function need to run on the same core...
User avatar
Bianco
XCore Expert
Posts: 754
Joined: Thu Dec 10, 2009 6:56 pm

Post by Bianco »

A nonblocking read can be done with a select statement:

Code: Select all

   select {
       case c :> var :
           // do something
           break;
       default:
           break;
  }
This code will set up an event for a channel receive and enables the event.
If something is available in the buffer it will execute first case.
If nothing is available the event will be disabled (default case).