Unintended Task launched, best way to Debug

Technical questions regarding the XTC tools and programming with XMOS.
shaw
Experienced Member
Posts: 67
Joined: Fri Mar 25, 2011 12:36 am

Unintended Task launched, best way to Debug

Post by shaw »

We are working on a new project on XU316-1024-FB265-C32, based on Xmos USB Audio 2 development software kit. We are trying to optimize certain tasks and we are trying to make sure we have a good handle on the overall task structure. During a analysis of running threads we realized that one of the tile 1 threads was not intentionally launched in our software. Output from (gdb) info threads is listed here:

15 tile[1] core[7] rx_bit_ep () at .../wkspace/lib_uart/lib_uart/src/multi_uart_rx_8chan.S:128
14 tile[1] core[6] (dual issue) at .../wkspace/lib_uart/lib_uart/src/multi_uart_tx.xc:230
13 tile[1] core[5] (dual issue) at .../wkspace/lib_xua/lib_xua/src/core/mixer/mixer.xc:444
11 tile[1] core[3] (dual issue) at .../src/extensions/uart_tile1.xc:93
10 tile[1] core[2] (dual issue) at .../src/extensions/tile1_control.xc:821
9 tile[1] core[1] (dual issue) at .../wkspace/lib_xua/lib_xua/src/core/audiohub\xua_audiohub_st.h:12
8 tile[1] core[0] (dual issue) at .../wkspace/lib_xua/lib_xua/src/core/audiohub/multiPin.xc:206
12 tile[1] core[4] 0x00088afa in ?? ()


Thread 12 on tile[1] core[4] is confusing how it was launched. Are there any clues in the "Info Threads" output, AND what are some ways to try to identify where in our code this task is being created, so we can remove it. Thanks for any help.
User avatar
infiniteimprobability
Verified
XCore Legend
Posts: 1170
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

It can sometimes help to switch to the task type "t 12" to switch to that thread and then do a backtrace "bt" to look at the call stack.
Engineer at XMOS
User avatar
xhuw
Verified
Active Member
Posts: 58
Joined: Wed May 22, 2024 2:36 pm

Post by xhuw »

Just been thinking about this - xgdb supports "resource watchpoints" that break whenever a resource is accessed. Spawning a thread on an xcore usually requires adding the thread to a "synchroniser," which is a kind of resource. The IDs of the synchronizers on an xcore are:

0x3,0x103,0x203,0x303,0x403,0x503,0x603.

So, for example, reswatch 0x3 will trigger a breakpoint when that synchroniser is configured. We don't know which synchroniser is used for your thread, so you will have to try all of them
XMOS Software Engineer

Image
shaw
Experienced Member
Posts: 67
Joined: Fri Mar 25, 2011 12:36 am

Post by shaw »

(gdb) thread 12
[Switching to thread 12 (tile[1] core[4])]#0 0x00088afa in ?? ()
(gdb) bt
#0 0x00088afa in ?? ()
#1 0x00088af8 in __start_core ()
(gdb)

Tried multiple times: run, randomly stop, check bt and continue running. Always the same result as above. Tried restarting multiple times and also same result. Seems stuck here.
User avatar
infiniteimprobability
Verified
XCore Legend
Posts: 1170
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Hmm, that doesn't help much.. sorry about that. My next step would be to grep/search for instances of par in the source. Looks like you are running the 8 channel UART and USB audio audiohub with mixer enabled. Worth checking those.
Also, if you are using user_main.h to launch stuff, then bear in mind that any task called there gets inserted into the main par statement. Even if it is a function that returns, it will be waiting on other tasks (which don't return) to synch at the join, which will never happen because there are many forever tasks on tile[1] It is something on tile[1]..

so in user main you may want something like:

Code: Select all


void mysetup_then_run_task(chanend c){
     do_some_setup(); // function returns
     run_my_forever_task(c); // does not return
}


#define USER_MAIN_CORES \
	on tile[1]: {\
		mysetup_then_run_task(c);\
	}\

Engineer at XMOS
User avatar
Ross
Verified
XCore Legend
Posts: 1216
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Do you have a thread that started up then exited/returned? Perhaps it saved some global state then returned?

If so, it will be sat on a ssync instruction waiting for others threads in the par to join (expect it to be "stuck" in __start_core). The thread won't be consuming any resources, the thread won't be scheduled (unless you have changed the thread mode) so don't worry too much about that. The biggest issue you will have here is you won't be able to run 8 threads on that tile (the mapper will barf) without a modification of the scheme employed.

By the way, later toolsets will give nicer gdb output, eg:
dump.png
(EDIT: cross post but still relevant!)
You do not have the required permissions to view the files attached to this post.
Technical Director @ XMOS. Opinions expressed are my own
shaw
Experienced Member
Posts: 67
Joined: Fri Mar 25, 2011 12:36 am

Post by shaw »

infiniteimprobability: Thanks for the clue regarding user_main.h. Looks like it might be an I2C task, that I have to handle properly.
Ross: Thanks for observation. Regarding New Tools, I will upgrade during some down time. I do have a follow-up question regarding thread priority. Probably best to start a new thread.
User avatar
Ross
Verified
XCore Legend
Posts: 1216
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

If you copied the reference design app it will be the saving off of the i2c interface to a global (to be used from AudioHwConfig() etc callbacks. You can save this off before running any other task on tile[1].
Technical Director @ XMOS. Opinions expressed are my own