https://www.xmos.com/published/xmos-xs1 ... ion=latest
Read page 22-24 regarding the END token that closes the channel.
Using Channels to effect asynchronous threads
PAUSE....interesting. Have to look into that.
partly what is needed, depending on conditions in thread2.
My original plan was to use two XC channels, kind of a circular Stop & Go.
Hm........
EDIT: Perhaps the OUTCT(I) and CHECKCT(I) will do the job. (?)
But if thread1 is not ready to rx the data it blocks thread2 from proceeding. Which isIt will open the channel, send the data, and close the channel again, making the switch free to use for other channel messages from other threads.
partly what is needed, depending on conditions in thread2.
My original plan was to use two XC channels, kind of a circular Stop & Go.
Hm........
EDIT: Perhaps the OUTCT(I) and CHECKCT(I) will do the job. (?)
What is it that you *really* want to do? You have a bunch of "clients"
and a "server", and then what? They talk and stuff? And you want
some of them to block sometimes, it seems?
We need more details to give you any good advice ;-)
and a "server", and then what? They talk and stuff? And you want
some of them to block sometimes, it seems?
We need more details to give you any good advice ;-)
Sometimes you have a main thread always running and many service/slave threads like a LCD, buttons, UART etc.
A solution is to use a select with a default in each service threads. Each service thread can cont. to run, but when the main threads sends a message on the channel, it will instead answer and thereafter cont. it´s own service stuff*.
This way the main thread will never block, and it can ask any service for data anytime.
If the main thread is running in an infinite loop you may send a message to the slave but wait until the next loopiteration for the readback to hide the small delay, depending on the priority of the threads.
*if a service thread collects alot of data, you may instead send a pointer/reference to the memory over the channel to the main thread avoiding stalling the services with a large channel data transfer (but only if the two threads are on the same core).
A solution is to use a select with a default in each service threads. Each service thread can cont. to run, but when the main threads sends a message on the channel, it will instead answer and thereafter cont. it´s own service stuff*.
This way the main thread will never block, and it can ask any service for data anytime.
If the main thread is running in an infinite loop you may send a message to the slave but wait until the next loopiteration for the readback to hide the small delay, depending on the priority of the threads.
*if a service thread collects alot of data, you may instead send a pointer/reference to the memory over the channel to the main thread avoiding stalling the services with a large channel data transfer (but only if the two threads are on the same core).
The main thread *does* block in this case, until the client thread is readylilltroll wrote:A solution is to use a select with a default in each service threads. Each service thread can cont. to run, but when the main threads sends a message on the channel, it will instead answer and thereafter cont. it´s own service stuff*.
This way the main thread will never block, and it can ask any service for data anytime.
to answer (that is, is executing that select statement). The delay should be
small (or you have a big problem), but it is certainly not negligible.
What's that? This isn't pthreads or similar, thank goodness :-)priority of the threads
- Folknology
- XCore Legend
- Posts: 1274
- Joined: Thu Dec 10, 2009 10:20 pm
- Contact:
No swearing on this channel please ;-)pthr#*ds
N.B. 'We prefer the term artificial threads..'
What I was looking to do is toggle a channel on and off and use this as a variable time length go/no-go switch for threads on separate cores.
(I have plenty to read and play with right now.)
case 1:
(thread X)
LOOP.
wait for external input to change.
input = data.
send channel data.
// thread is blocked
Back to LOOP.
(thread Y)
AGAIN.
long delay.
long delay.
read channel data.
// channel is established. Thread X is unblocked.
Do processing on data.
Back to AGAIN.
The problem here is thread Y will keep looping on the old data.
It will not wait until the next change on thread X input.
case 2:
(thread X)
LOOP.
wait for external input to change.
input = data.
send channel data. // possible block waiting for read from Y.
Back to LOOP.
(thread Y)
AGAIN.
long delay.
long delay.
read channel data. // Possible block waiting for send from X.
// channel is established. Thread X is unblocked.
Kill channel. ****
Do processing on data.
Back to AGAIN.
This time the channel(ends) must be re-established or either thread could be blocked.
This is not a real life problem. Just part of the learning curve.
Anyway, just looking for/trying different possibilities.
For now, as per the suggestions made, it's "Back to the books".
Geez :( ...When will I know it all? :)
(I have plenty to read and play with right now.)
case 1:
(thread X)
LOOP.
wait for external input to change.
input = data.
send channel data.
// thread is blocked
Back to LOOP.
(thread Y)
AGAIN.
long delay.
long delay.
read channel data.
// channel is established. Thread X is unblocked.
Do processing on data.
Back to AGAIN.
The problem here is thread Y will keep looping on the old data.
It will not wait until the next change on thread X input.
case 2:
(thread X)
LOOP.
wait for external input to change.
input = data.
send channel data. // possible block waiting for read from Y.
Back to LOOP.
(thread Y)
AGAIN.
long delay.
long delay.
read channel data. // Possible block waiting for send from X.
// channel is established. Thread X is unblocked.
Kill channel. ****
Do processing on data.
Back to AGAIN.
This time the channel(ends) must be re-established or either thread could be blocked.
This is not a real life problem. Just part of the learning curve.
Anyway, just looking for/trying different possibilities.
For now, as per the suggestions made, it's "Back to the books".
Geez :( ...When will I know it all? :)
This isn't true. In Thread Y, the statement "read channel data." will block until new data is sent from Thread X. I think you are misunderstanding channels.The problem here is thread Y will keep looping on the old data.
Channels are not memory stores, but rather FIFO paths of communication. Once you read the data from the channel, the data is no longer in the channel. Reading it again would simply block until new data is provided. Therefore, there is no "old data" it would keep receiving.
Again, if you don't want a channel communication to block, use a select guard.
You got that right. :-(I think you are misunderstanding channels.
Good thing this place is here. :-)
RP181 wrote:
That paragraph made the logic sink in.
It should be added to the tutorial for thick heads like mine.
Also, in the 'Using Channels in XC' tutorial, in the paragraph below the code section that contains;
Pong received Ping
Ping received Pong
Pong received Ping
it states;
and maybe use, 'crash or block'?
Anyway.......FREE beer for all, and many thanks for the help. :)
That's it! :)Channels are not memory stores, but rather FIFO paths of communication. Once you read the data from the channel, the data is no longer in the channel. Reading it again would simply block until new data is provided.
That paragraph made the logic sink in.
It should be added to the tutorial for thick heads like mine.
Also, in the 'Using Channels in XC' tutorial, in the paragraph below the code section that contains;
Pong received Ping
Ping received Pong
Pong received Ping
it states;
input, input?Channels require symmetric input and output, that is for every input there must be an input, if this isn't observed it will crash the program.
and maybe use, 'crash or block'?
Anyway.......FREE beer for all, and many thanks for the help. :)