par statement

Technical questions regarding the XTC tools and programming with XMOS.
daleonpz
Member++
Posts: 26
Joined: Thu Nov 04, 2010 1:18 pm

par statement

Post by daleonpz »

i have a doubt, what exactly does par statement work?, i dont know how many times it executes or if it neccesary to use while(1)..

i will be looking forward to your responses.


User avatar
TSC
Experienced Member
Posts: 111
Joined: Sun Mar 06, 2011 11:39 pm

Post by TSC »

That sounds like an easy one, so maybe I can answer it.

No while loop is necessary. Each function call within par{} triggers the start of a thread, so the body of par{} executes once only. Each thread will then continue running on its own.

Code: Select all

// For XS1-G4 4-core XMOS device.
int main(void){
	chan ledch[4], ledpat;	// For LED outputs

	par {
		on stdcore[0]: percoreled(ledch[2], x0ledA, x0ledB);
		on stdcore[1]: percoreled(ledch[3], x1ledA, x1ledB);
		on stdcore[2]: percoreled(ledch[1], x2ledB, x2ledA);
		on stdcore[3]: percoreled(ledch[0], x3ledA, x3ledB);

		on stdcore[1]: ledlistener(ledpat, ledch[0], ledch[1], ledch[2], ledch[3]);
		on stdcore[1]: test(ledpat);
	}
}
daleonpz
Member++
Posts: 26
Joined: Thu Nov 04, 2010 1:18 pm

Post by daleonpz »

TSC wrote:That sounds like an easy one, so maybe I can answer it.

No while loop is necessary. Each function call within par{} triggers the start of a thread, so the body of par{} executes once only. Each thread will then continue running on its own.

Code: Select all

// For XS1-G4 4-core XMOS device.
int main(void){
	chan ledch[4], ledpat;	// For LED outputs

	par {
		on stdcore[0]: percoreled(ledch[2], x0ledA, x0ledB);
		on stdcore[1]: percoreled(ledch[3], x1ledA, x1ledB);
		on stdcore[2]: percoreled(ledch[1], x2ledB, x2ledA);
		on stdcore[3]: percoreled(ledch[0], x3ledA, x3ledB);

		on stdcore[1]: ledlistener(ledpat, ledch[0], ledch[1], ledch[2], ledch[3]);
		on stdcore[1]: test(ledpat);
	}
}
so you mean that each thread will run undefinitely?.. because in my program, everything is running well but in some point just one thread keep working for awhile and then stop like the others.
daleonpz
Member++
Posts: 26
Joined: Thu Nov 04, 2010 1:18 pm

Post by daleonpz »

just in case, here's my code

Code: Select all

int main(void)
{

	streaming chan c1,c2,c3,c4,c5,c6;

	par{
		calculo(c1,c2,c3,c4,c5,c6);
		thread1(c1,c2);
		thread2(c3,c4);
		thread3(c5,c6);
		}
	return 0;
}
User avatar
TSC
Experienced Member
Posts: 111
Joined: Sun Mar 06, 2011 11:39 pm

Post by TSC »

Yes. Each thread will run indefinitely (forever, unless an error occurs).

If an error does occur due to something like an illegal type conversion or whatever, the XDE console should show some sort of error message:

xrun: Program received signal ET_ECALL, Application exception.
[Switching to stdcore[0] hwthread 3]

If you don't see an error message, I'd say the most likely explanation is that the thread is getting stuck in a loop or execution is blocked on some condition such as a channel receive or port state change. You'd have to do some debugging to find the problem.

EDIT:
I see you have posted a bit of code. Everything in main{} looks alright to me (although I have only used normal channels, not streaming). I imagine the problem is in one of the other functions. Can you post more code?
daleonpz
Member++
Posts: 26
Joined: Thu Nov 04, 2010 1:18 pm

Post by daleonpz »

im just testing concurrency and streaming.

Code: Select all

void calculo(streaming chanend c1, streaming chanend c2,streaming chanend c3,streaming chanend c4,streaming chanend c5,streaming chanend c6)
{  int m[] = {1,2,3,4,5,6};
   while(1){
	printf("hola calculo\n");
	for (int i=0; i<6;i++)
	{
		m[i]=m[i]*2;
	}
	c1 <: m[0];
	c2 <: m[1];
	c3 <: m[2];
	c4 <: m[3];
	c5 <: m[4];
	c6 <: m[5];
}
}

void thread1(streaming chanend c1, streaming chanend c2)
{	int n;
	while (1){
	printf("hola thread1\n");
	c1 :> n;
	printf("soy el hilo 1 y mi numero es %i\n",n);
	}
}

void thread2(streaming chanend c3, streaming chanend c4)
{	int n;
	while (1){
		printf("hola thread2\n");
	c3 :> n;
	printf("soy el hilo 2 y mi numero es %i\n",n);
	}
}

void thread3(streaming chanend c5, streaming chanend c6)
{	int n;
	while (1){
	printf("hola thread3\n");
	c6 :> n;
	printf("soy el hilo 3 y mi numero es %i\n",n);
	}
}

User avatar
TSC
Experienced Member
Posts: 111
Joined: Sun Mar 06, 2011 11:39 pm

Post by TSC »

The problem is calculo() communicates with each other thread over two channels. But thread1/2/3() are only reading from one channel.

To fix the program, make thread1/2/3() read from both channels.

Code: Select all

void thread1(streaming chanend c1, streaming chanend c2)
{   int n, m;
   while (1){
   printf("hola thread1\n");
   c1 :> n;
   c2 :> m;
   printf("soy el hilo y mis numeros %i, %i\n",n, m);
   }
}
Also, streaming channels are unnecessary unless you need higher speed. I think normal channels (with synchronization) are easier to work with.
User avatar
daveg
Member++
Posts: 28
Joined: Thu Dec 10, 2009 7:25 pm

Post by daveg »

Threads _can_ run forever, if you put a while(1) or equivalent in your thread code, but if the function called in the par block returns then this will terminate the thread. (They don't _have to_ run forever)

The par block as a whole won't complete until all threads in it have terminated, at which point it will synchronize and then continue with whatever is after the par block. Multicore mains (with `on stdcore[n]' specifiers on the threads) can't have anything in them except one par block, so this is a bit simpler for those. (This is to allow xmap to do the cross-core thread setup and breakdown at build-time, as dynamic networks aren't supported in the tools [as far as I know])
User avatar
jonathan
Respected Member
Posts: 377
Joined: Thu Dec 10, 2009 6:07 pm

Post by jonathan »

daveg wrote:This is to allow xmap to do the cross-core thread setup and breakdown at build-time, as dynamic networks aren't supported in the tools [as far as I know]
They are supported by the architecture though, right?
Image
User avatar
daveg
Member++
Posts: 28
Joined: Thu Dec 10, 2009 7:25 pm

Post by daveg »

jonathan wrote:
daveg wrote:This is to allow xmap to do the cross-core thread setup and breakdown at build-time, as dynamic networks aren't supported in the tools [as far as I know]
They are supported by the architecture though, right?
Yes. You can also start off threads and leave them going while you do something else, but XC doesn't allow this, since par statements sync up when the child threads terminate. (So no async threads in XC, really) This would be possible with a different language if you wanted.