What you create with the Bela_createAuxiliaryTask() functions is essentially a Xenomai thread with some handful features:
- an internally-managed condition variable allows to easily schedule the user-defined function as needed calling
Bela_scheduleAuxiliaryTask()
- cleaning up of the thread is handled automatically by the backend (as long as the user function returns quickly when
Bela_stopRequested() returns true. The user-defined function is guaranteed not to be running and not to be called again by the time cleanup() is called.
- being a Xenomai thread, it can access Xenomai functions such as reading/writing on the RT side of a
Pipe object.
- being a Xenomai thread, when it tries to access non-RT services (e.g.: reading/writing to/from file/network/UART whatev, or even the nonRt side of a
Pipe), it will work just fine and it will be scheduled by the Linux scheduler
In other words, an AuxiliaryTask:
- is more convenient than either a std::thread/pthread or raw Xenomai task in that:
- the user-defined function can be scheduled in a Xenomai real-time safe way from the audio thread or other AuxiliaryTask (or more in general any Xenomai thread).
- you don't have to clean it up manually when the program ends
- is more convenient than a raw Xenomai thread in that you don't have to set the thread and scheduler parameters manually
- is more convenient than
std::thread or pthread in that it can access Xenomai services and its priority can be set easily upon creation
For these reasons, an AuxiliaryTask matches most use cases: you can use it for a real-time priority DSP co-routine to the audio thread (see Audio/FFT-phase-vocoder) or for Linux I/O activities.
rrvvzz How does this RT / non RT distinction work?
When we talk about "RT" thread we mean a thread that is a Xenomai task and does not call any Linux services. These prerequisites mean that the thread will run in Xenomai "primary mode" (aka Xenomai mode) and is subject entirely to the Xenomai scheduler and therefore it can preempt almost immediately any user- or kernel- space Linux threads (i.e.: its scheduling is largely independent of whatever Linux is doing).
By non-RT thread we mean either a non-Xenomai thread or a Xenomai thread which uses Linux I/O services and runs in "secondary mode" (aka Linux mode) . In this case, the thread will be subject to the Linux scheduler and therefore will not be able to always immediately preempt Linux kernel threads even when it has a high priority.
rrvvzz but the demo includes a function that receives OSC messages, which is not in any auxiliary task
Now, to your specific case. In the Communications/OSC-Pipe example, the on_receive() function is passed as an argument to OscReceiver::setup(). This function is called by OscReceiver whenever a new message is available. This is called from a non-RT thread (it's a std::thread managed internally by OscReceiver), so it writes to the NonRt side of the Pipe, The RT thread (the audio thread in this case, which executes the render() function), can safely read from the Rt side of the Pipe, process the incoming data and write a response (in this case the pointer to be deleted) back into the Pipe.