Create task without starting it?

I am migrating a code base over from eCos to FreeRTOS. In eCos, you can create a thread and then resume it at a later time, e.g., the thread creation does not automatically start running the thread. I would like to do something similar with FreeRTOS because we do some initialization and want all the threads to start after that initialization. Is this possible with FreeRTOS? I didn’t see a task creation function that would take a flag or anything to not start the thread.

Are you creating the threads before starting the scheduler? If so, you can create the thread and then suspend it - so when the scheduler starts it is already in the suspended state.

No, they may be created at any time, mostly after the scheduler is started.

If this feature doesn’t exist, would a PR with an implementation be allowed, or should I just implement locally?

In addition to Richard’s proposal you might simply implement your own task code wrapper with vTaskSuspend(NULL); as task code preamble (right before the real task code begins) along with a taskStart function just initially resuming this task.
This works regardless if the scheduler already runs or not.
I wouldn’t create a PR for this rather specific / eCos like use case.

If we can think of a backward compatible way of implementing this then we could add it as a new feature.

I can only think of an extended API like xTaskCreateSuspended putting it into the suspended instead of ready list… This would also avoid tailored (self-suspending) task code.

there are numerous ways of implementing this… for example, the task parameter could point to a structure one parameter of which is a (n initially owned) semaphore that must explicitly signalled to start the thread fn.

I agree that it could be a useful feature, but as Richard Barry says, the problem is backward compatibility. I think this really would need a new set of creating functions to do, and that starts to make things start to explode as we already have static and dynamic, and then we have create restricted (which can only be done as static).

As has been mentioned, you can do this sort of already in a couple of different ways.

One is wrapping the task function with a function that suspends/blocks itself and then calls the normal task function.

Another is to create it at a lower priority than you, then suspend it, then change its priority to what you want (if it would be equal or higher than yours).

You can also just define your task to start with the blocking/suspending unless there is a real reason that needs it to start suspended (my task wrapping class have that issue, you want to let the task class finish constructing before letting the task that will use that class fully start)

Except for that wrapping issue, I find little need to start a task suspended, as either I will be creating the task I will need some point in the future at startup time, or I really need it NOW, so don’t want to create it suspended.

There is also the concept that in most cases ‘suspending’ a task if rarely what you want to be doing, the task should be naturally blocking until it has something to do, at which point that work arriving causes it to unblock and run…

Thanks everyone for your suggestions. I’ll take a look at each one and decide which will work best for me. Thanks again!

Be aware that there is a drawback using the cheap self-suspend approach. There is a chance of a subtle race condition resuming the created task not yet self-suspended as this is part of the task code and the task needs a chance to run…
Resuming a non-suspended task does nothing, as mentioned task suspend/resume is a special tool. So you’d need to take some extra measures (e.g. boosted create prio, poll task state using eTaskGetState, …) to handle this.
Using a real sync object like a semaphore or something else as @RAc proposed would be safe.
Getting rid of the splitted create/start approach would avoid all of this :wink:

Thanks, Hartmut. I also agree with you that adapting this OS specific feature is probably not worth adding to the standard API set. I remember porting something from Kadak’s AMX (which had this feature) to FreeRTOS, and when I came across the same porting issue, I looked at the original code closer just to discover that it would have been much cleaner to restructure the code in the first place, so that’s what we did.

That said, I can think of a more generic approach where you could split a FreeRTOS task into an init phase followed by the infinite loop. The first part could be traversed as soon as the scheduler allows the task to run, whereas the second part would require explicit triggering. If the first part is empty, semantics are equivalent to eCOS and AMX’s start suspended.

But again, every such feature leaves the sour taste of “RTOS lock-in” on the tongue, because if it’s part of the OS, it’ll make it harder to port to another RTOS later on and thus discourage a migration. IMHO there should be a very good reason for any such addition which would be true added value. Like @richard-damon and @hs2 , I don’t see a true added value in this; it’s straightforward enough to implement custom tailored. Maybe add a sample to the plus tree?

Well you are free to define your task the way you want, so you can write that initial section that will run as soon as it can, then you can put an explicit block till you are ready to go to the second part.

It is only if you are using some ‘special sauce’ of the OS to make that explicit block be implicit that you get into trouble, and that is what creates the locking.

I would say also that Io would actually NEVER use ‘suspend’ for this operation, due to the race conditions, but a direct-to-task notification wait, as that gets rid of the race completely.