Ending/stopping a parrallel task and how to restart tasks

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Folknology wrote:
But to be fair at this point I do not fully understand the exact problem that you are trying to solve
regards
Al
I just want to run 3 programs, one at the time.

1) Run the program that estimates the left channel transfer function - store the result in flash or in SRAM memory.

2) Run the (same) program that estimates the right channel transfer function - store the result in flash or in SRAM memory.

3) Run multichannel adaptive filters that uses the prior estimates as information for the "secondary channels" (The primary channels are automatically adapted).

All this without getting out of channel end resources. Like a malloc() for channels :D

Step 1 2 and 3 are working on there own - but not when I try to run the like 1,2, 3

Also if you press a button during step 3, the program should start running step 1&2 again to re-estimate the channels.


Probably not the most confused programmer anymore on the XCORE forum.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

how many threads does 1 or 2 require are they assumed concurrent, what are the results for the transfer function?
you mention chanend resource limitations , how many are we talking about, does this mean that you are limited to using streaming channels hence the limitation or is it possible to use channels/transactions which have lesser performance but not the resource limitations?
3 sounds like the complicated bit in terms of channels can you expand on it a bit more?
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Hmm after a little thought:

I would be tempted to run part 3 first, rather than have it run by the completion of 1 and 2. But on its first run it will realise that the transfer function is invalid and thus block until it has run 1 and 2 and then continue until the transfer function is made invalid again by another thread button thread. Actually not even sure the button thread needs to be a thread.

Does this make sense from a 50,000 feet view?
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Folknology wrote:Also I just noticed, shouldn't 'control' be passed as a reference in your example?
moved the topic

I have one &, do I need more of them ?

(And in the headers for I2S_slave and so one, but the headers are not shown in that example)
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Ok my bad, its because I could not see the headers
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Right I just tried an exercise with reusing a channel to see if it works, because trying to work it out from the ambiguous XC manual wasn't helping:

Code: Select all

# include <platform.h>
# include <stdio.h>
# define CHARS 15

char msg1[] = "Hello channel1";
char msg2[] = "Hello channel2";

void txthread(chanend x,char data[],int size){
  for(int i = 0; i < size;i++){
    x <: data[i];
  }
}

void rxthread(chanend x, char rxbuf[],int size){
  for(int i = 0; i < size; i++) {
    x :> rxbuf[i];
  }
}

void runthreads() {
  char rxmsg[CHARS];
  chan c;
  par{
    txthread(c,msg1,CHARS);
    rxthread(c,rxmsg,CHARS);
  }
  printf("par 1 recieved %s\n",rxmsg);
  par {
    txthread(c,msg2,CHARS);
    rxthread(c,rxmsg,CHARS);
  } 
  printf("par 2 recieved %s\n",rxmsg);
}

int main ( void ) {
  runthreads();
  return 0;
}
It does work

Code: Select all

:-$ xcc chan-test.xc -target=XK-1 -o bin.xe
:-$ xrun --id 0 --io bin.xe
par 1 received Hello channel1
par 2 received Hello channel2
Thus unless I'm missing something in my logic, the previous diagnosis about your channels issues are not these. perhaps something more complex is happening with the channels?

regards
Al
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

What about if the receiving thread can't know how much data that will be sent; since that was my initial problem: To end all other threads when the first one has finished it's task.

After ending the first parallell tast, start a new parallel task in sequence.
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

I can run but I cannot hide :D

Emigrating to the XDK+XAI from the USB Audio took some time, but now is the time to solve it - this time for multi-Core => Using channel com.

Code: Select all

int main(){
	streaming chan c_render,c_Audio, c_Audio_to_LCD, c_I2S_to_resampling[2],c_res_AUDIO0,c_res_AUDIO1,c_error;
	chan c_buttons,c_vector[2],c_tou;
...
The threads that should be stopped now looks like this:

Code: Select all

...
par{
		on core_DSP0:{
		w_vec FXfir;
		initvector(FXfir);
		par{
			resample(c_I2S_to_resampling[0],c_res_AUDIO0);
			send_vec(c_vector[0],FXfir);
			lmsfind(c_res_AUDIO0,FXfir);
			}
		}
		on core_DSP1:{
		w_vec FXfir;
		initvector(FXfir);
		par{
			resample(c_I2S_to_resampling[1],c_res_AUDIO1);
			send_vec(c_vector[1],FXfir);
			lmsfind(c_res_AUDIO1,FXfir);
			}
		}
...
Meanwhile this code is still running, without making the c_I2S_to_resampling channel to stall

Code: Select all

...
		on core_buttons: keys(p_keys,p_keys_led,c_buttons);
		on core_LCD :{
		databuf buffer={{40,40,40,40,40,40,0,0},{50,50,50,50,50,50,50,50}};
		linebuffer frame;
		par{
		 lcd_init(frame,c_render, p_lcd_hsync, p_lcd_dclk, p_lcd_dtmg, p_lcd_rgb);
		 generate_lcd_screen(frame,c_render, c_vector,c_buttons,c_tou,buffer, p_LED_3_2);
		 peakhold(c_Audio_to_LCD, buffer);
		 touch(c_tou);
		}
	}
	on core_expansion : {
		mixer MIX;
		print_info();	 
		init_pll(scl,sda,MCLK);
		printstr("XAI clock multiplier generates ");
		printint(MCLK);
		printstrln(" kHz master clock");
		reset_codec(rst);
		init_mixer(MIX);
		init_codec(scl, sda);
		par {
			fsgen(1000, fs);
			loopback_vec(c_Audio); //Loopback channels that isn't resampled
			{
			 mswait(1000);
			 iis(r_iis, c_Audio, c_Audio_to_LCD, c_I2S_to_resampling,MIX);
			}
			}
		}
  	}
	return 0;
I guess their is 2 possible outcomes. I become a loooser or I start understanding things on an instruction level.
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Well, their must exist a very elegant solution in my case, since threads waiting for channel-data pauses.
I do not plan to run more that 4 threads per Core. Meaning that I can have 4 threads paused meanwhile.
Since I will not attempt to dynamically load code, I wouldn't save any memory by "Killing" either.
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Anyone know if there is more documentation about this usages:

From the FREQ example for the XDK

Code: Select all

        
case poison :> int x:
            before <: 0x80000000;
            outuint(left, 0x80000000);
            outct(left, XS1_CT_END);
            outuint(right, 0x80000000);
            outct(right, XS1_CT_END);
            inct(left);
            inct(right);
            led_adc <: 1;
            return;
        }
I have missed that it could be used for channels, not only ports:

Code: Select all

case poison :> int x:
Can it only be used together with a case ?
Probably not the most confused programmer anymore on the XCORE forum.