Queue creation after Scheduler starts

amilaperera wrote on Tuesday, March 06, 2018:

Hi,

Does Queue creation after scheduler starts causes undefined behaviour?

I have a initialization task that gets started first along with the scheduler, then the initialization task in turn creates a bunch of other tasks and queues. I observer a uncertain behaviours with this design. I even observe that lower priority tasks not waking up the higher priority tasks that are waiting on queues.
When I change my code as to create all the tasks along with the queues before the scheduler starts everything seems to be fine.

I can’t provide a minimally completed example as of now, since my code goes through lot of custom C++ wrappers. But do you have any thoughts in this ?

Thank you in advance.
Amila.

rtel wrote on Tuesday, March 06, 2018:

Don’t know what your custom C++ wrappers are doing, but there is nothing in the base C code that prevents queues being created after the scheduler has started. Do you check the return value of the queue create function to check the queue was created successfully before you try using it?

richard_damon wrote on Tuesday, March 06, 2018:

As Richard Barry says, queue creatation after the scheduler starts is fine. What you do need to be careful of is that you create the queue before you use it, so you want to create the queue before you create the tasks that will be using the queue, or you need to add a lot of tests that the queue creation has happened in the tasks.
The other thing to watch out for is that you don’t create anything using a local variable as storage in the initialization task if it terminates (and destroys that local variable).

That said, my standard is to create as much as I can before the scheduler is started to avoid syyncronization issues, so that generally says all my tasks and queues. In fact with my own C++ wrappers, most tasks and queue are created as global objects, so they are created before main even starts, and main is often just a call to start up the scheduler.

One thing to watch out is to NOT create things as local variables in main, as many ports will reuse the main stack as the interrupt task, so those objects will get overwritten.

amilaperera wrote on Friday, March 09, 2018:

Hi,

Thank you very much for the responses. I didn’t have enough time to dig deep into these issues, but will keep posting when I do more investigations on this. I will take the above comments into consideration as well.

Thanks for the feedback.

amilaperera wrote on Friday, March 09, 2018:

Hi Richard Damon,

One thing to watch out is to NOT create things as local variables in main, as many ports will reuse the main stack as the interrupt task, so those objects will get overwritten.

Actually I’ve came across this interesting thread before.
https://www.freertos.org/FreeRTOS_Support_Forum_Archive/January_2015/freertos_Main_stack_pointer_reset_when_starting_the_scheduler_e5a776c1j.html

Having an initialization task and creating my all variables within the initialization task(of course the task finally does a ‘WFI’ without returning as to disallow the destructors executing) was an attempt to avoid that beign happened. But, I think I need more investigations into the matter.

Will let you know about the findings later.

Thanks.

richard_damon wrote on Friday, March 09, 2018:

You don’t need to go to heroics to avoid the destructors from running, just don’t terminate the task, and end in an infinite loop of vTaskDelay(very big number) to keep the variables alive. Doing this though doesn’t solve the issue that you need to be very careful on the order you create things to make sure you create no task before you have created all the resources it needs, one of the reasources it needs. You also need to be VERY careful in creating tasks that are wrapped in a clase in the constructor for a base for that task, as the task will be created before the object creation is completed, and possibly start to run.

This is why I really try to create everything I can before starting the scheduler, and creating things as global or heap objects, not local variables.

amilaperera wrote on Tuesday, March 27, 2018:

Hi,
I think I figured out the reason behind the weired behaviour I explained in my first mail in this mail thread. Purely for the purpose of record let me share this information with you.
The issue seems to be nothing related to queues and its relation to the scheduler starting time, but purely linked to the way I call xTaskCreate().

In my C++ abstration, I had a notion of Un-named tasks.
Below is how I call xTaskCreate() inside my C++ API Thread::Start(). name_ denotes the std::string object that I store in the Thread class object and is accepted when calling the Thread constructor.

    BaseType_t ret = xTaskCreate(
        ThreadFunctionProxy, name_.empty() ? nullptr : name_.c_str(),
        static_cast<U16>(stack_depth_ / sizeof(StackType_t)),
        this,
        priority_,
        &handle_);

I’ve mistakenly assumed that NULL is a valid argument for pcName in xTaskCreate() api. Having a look at prvInitialiseNewTask() function it seems that the function strictly assumes thread name to be non-null value or otherwise the TCB gets corrupted since the function dereferences a NULL pointer.

So, my Initialization task as per the 1st mail was created as an un-named task while all the other tasks created inside the initialization task are created as named tasks. The initialization task’s TCB should be somehow corrupted as it is dereferencing a NULL pointer in the case of my un-named task hence the observed abnormal behaivour.

Thanks.
BR,
Amila Perera.