Can't create >1 thread and call into assembly!

Technical questions regarding the XTC tools and programming with XMOS.
TjBordelon
Active Member
Posts: 39
Joined: Mon Jul 29, 2013 4:41 pm

Can't create >1 thread and call into assembly!

Post by TjBordelon »

Hey guys,

Is anyone successfully using multicore and running >1 thread calling into assembly on a single core? I can't get this to work on either v12 or v13 of the tools, and I'm cut down to a barebones example.

My main.xc is simple, as it just calls 2 functions on one of the cores. That should give me 2 threads:

Code: Select all

 
#include <platform.h>
#include <xs1.h>
#include <xclib.h>

#include "tile0.h"



int main()
{

	par {

		on tile[0]: 	tile0_thread1();
		on tile[0]: 	tile0_thread2();

	}

	return 0;
}


I had to do the above because if I don't the debugger fails due to other bugs. So off we are in another file.. tile0.c... here it is:

Code: Select all


#include "tile0.h"
#include "xcore.h"



void some_asm_func();


void tile0_thread1( )
{
	some_asm_func();

}


void tile0_thread2()
{
	some_asm_func();
}

Simple. I can't figure out though why I get this error:

Code: Select all

Creating Modem_Debug.xe
../src/Modem.xc:(.text+0xe): Error: Meta information ("some_asm_func.nstackwords") for function "some_asm_func" cannot be determined.
../src/Modem.xc:(.text+0xe): Error:   lower bound could not be calculated (function is recursive?).
And you might wonder if I'm doing something nutty in assembly. Well, you tell me:

Code: Select all



	.text
	.align 4

	.globl some_asm_func
	.type  some_asm_func, @function


some_asm_func:
	retsp		0x00

Surely it's me. Surely I've done goofed it up. Anyone spot the error? I really feel like I'm just down to the fundamental hello world here and I fail.
User avatar
Bianco
XCore Expert
Posts: 754
Joined: Thu Dec 10, 2009 6:56 pm

Post by Bianco »

Try something like this:

Code: Select all

   .text
   .align 4

   .globl some_asm_func,"f{0}()"
   .type  some_asm_func, @function

   .globl some_asm_func.nstackwords
   .globl some_asm_func.maxthreads
   .globl some_asm_func.maxtimers
   .globl some_asm_func.maxchanends
   .linkset some_asm_func.nstackwords, 0
   .linkset some_asm_func.maxthreads,  1
   .linkset some_asm_func.maxtimers,   0
   .linkset some_asm_func.maxchanends, 0

   .cc_top some_asm_func.func, some_asm_func
   
some_asm_func:
   retsp      0x00
   
   .cc_bottom some_asm_func.func
It is a good idea to give the tools some more information so it can perform additional checks on resource usage etc :).

here's some info:

http://www.xmos.com/support/documentati ... nent=14808
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

You don't set "some_asm_func.nstackwords", as the error message
tells you. You should. There is documentation about this, but the
documentation page currently redirects onto itself which makes it
a bit hard to find stuff on it :-P

Let's use google instead... there you go.

(That was "xmos assembler filetype:pdf").
TjBordelon
Active Member
Posts: 39
Joined: Mon Jul 29, 2013 4:41 pm

Post by TjBordelon »

Yeay! That fixed it!! And BTW you guys were spot on. I figured it out over pancakes at the local diner. No internets or you guys would have saved me some hair.

The first thing that clued me in was that there seems to be no place to enter the stack size per core. Then it dawned on me. The compiler must be crawling the code to determine this.

For a single thread on a core it matters not. But for >1 thread this seems to matter as you'd expect. While every other toolchain lets you enter a manual stack size, this one tries to be smart. I wish I could just enter a value.

I'm surprised by default assembly (or ABI as they call it) functions seem to require the specification of a stack size. I had to explicitly say how much stack I was using in the function.

.globl xcore_waitsignal
.globl xcore_waitsignal.nstackwords
.linkset xcore_waitsignal.nstackwords, 2

.type xcore_waitsignal, @function

I would think the ABI would infer this from the rather obvious "entsp 0x2" in the function. Maybe say use that as the default. Nah. We'll display an obscure error instead.

Anyway, I had it tricked so it doesn't crawl the code by using:

on tile[0]: asm(" bl tile0_thread2");
on tile[0]: asm(" bl tile0_thread1");

Then you don't seem to have to specify anything. But who knows how it calculates stack size per thread if you do this. I do know it works to do it this way as well. It seems to be a way to trick the tools into not following the callchain into those functions.

Derp!

Thanks for the feedback. I think I'll take both suggestions and do a more complete description of the function to avoid further trouble. I see the few places this is mentioned in the manual. For some reason it didn't click that it applied in this situation but seems obvious now.