Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add and use a task_create API #16938

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

peterbarker
Copy link
Contributor

Recently we started to get thread-stuck in our CI:

2021-03-17T16:41:37.2038424Z AT-0161.0: AP: AP_Logger: stuck thread (write)

causing random failures.

This is probably due to moving the IO thread to being an actual thread (#16117). As an IO process in SITL the write() would've block in the main thread - but now it blocks in its own thread so the heartbeat isn't updated and we end up considering it stuck.

This new API is very similar to the thread_create API, except that it takes three functors - one for initialisation code, one for the body of the thread's loop and one for the delay to be used after the thread body is done.

This allows SITL to run the body of the task in the same way that the timer-proc and io-proc thread bodies are run by the scheduler - synchronously in the main loop as part of SITL scheduling. AP_HAL_ChibiOS creates a thread, and calls init(), then loops across calling the body and delaying according to the result of the get_delay_us call.

Moving to this method should ease debugging of thread-related things in SITL (in particular, the thread used by AC_Avoidance is difficult to work with in SITL). Some work on the abstraction might permit us to create some sort of task-group to consolidate some of the code around the io-proc and timer-proc facilities.

This has been lightly tested in SITL and on a Pixhawk4-Mini.

/*
create a new task
*/
FUNCTOR_TYPEDEF(TaskBodyMemberProc, uint32_t);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs this a comment explaining usage

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

task_ctx *t = (task_ctx *)ctx;
t->init[0]();
while (true) {
const uint32_t delay_us = t->body[0]();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment explaining the delay

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

create a new thread
*/
bool Scheduler::thread_create(AP_HAL::MemberProc proc, const char *name, uint32_t stack_size, priority_base base, int8_t priority)
uint8_t Scheduler::thread_create_find_priority(priority_base base, int8_t priority) const
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs comments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comment and renamed to calculate_thread_priority

@peterbarker
Copy link
Contributor Author

I've created a simpler, crappier, less-complete fix in #16978

@peterbarker peterbarker force-pushed the pr/task-create-api branch 3 times, most recently from 1e2e086 to d204153 Compare August 29, 2023 07:16
@peterbarker
Copy link
Contributor Author

peterbarker commented Aug 29, 2023

It's not free, being an alternative infrastructure to the existing thread_create method. I don't think this can't do anything the existing method can, however, so we could move entirely to this mechanism

Board               AP_Periph  blimp  bootloader  copter  heli  iofirmware  plane  rover  sub
Durandal                       240    *           248     256               424    256    288
HerePro             152                                                                   
Hitec-Airspeed      152                                                                   
KakuteH7-bdshot                136    *           144     112               48     184    128
MatekF405                      208    *           176     168               136    160    144
Pixhawk1-1M-bdshot             160                200     184               184    176    136
f103-QiotekPeriph   152                                                                   
f303-Universal      152                                                                   
iomcu                                                           152                       
revo-mini                      144    *           136     144               -16    128    136
skyviper-v2450                                    160                                     

@@ -666,6 +666,26 @@ void Scheduler::restore_interrupts(void *state)
chSysRestoreStatusX((syssts_t)(uintptr_t)state);
}

struct task_ctx {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could add a destructor to this to clean up the two members and then use new and delete in the usage - might make it slightly cleaner

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could add a destructor to this to clean up the two members and then use new and delete in the usage - might make it slightly cleaner

If I'm understanding your suggestion correctly that would involve moving doing this allocation into the constructor for struct task_ctx here?

Couldn't quite do that as you can't fail in a constructor. But I've pushed some patches on top which add an initialise method, and yes, I think it is an improvement, thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.... I've now removed the calls to malloc in here. I've no idea what I was thinking when I added those, but it seems to get by with just having the init/body procs as members of the context.

I've done a smoke-test on a CubeOrange here and it seems to do logging just fine-and-dandy.

@peterbarker peterbarker force-pushed the pr/task-create-api branch 2 times, most recently from 415a35c to 8bd6409 Compare August 30, 2023 01:38
@peterbarker peterbarker force-pushed the pr/task-create-api branch 2 times, most recently from 909785b to e7f701e Compare November 15, 2023 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants