thetechnobear ah cool, so you are shipping some externals in the build? where are they located?
No externals, they are built into libpd
.
thetechnobear std::thread, thanks that useful, as i didnt want to swap out unless absolutely necessary.
Your problem is the condition variable then, do you use it for the std::thread
to be woken up? When writing (partly-(portable code, I normally just poll a flag in memory from the non-RT thread. If going full-Xenomai, I use its own message-queues or RT-pipes (see some examples in core/AuxTask*.cpp
or in core/Midi.cpp
).
Anyhow, if you really need a condition variable, that should be a Xenomai one. So the deal with this is: just use plain-C pthread_cond_
and compile and link normally for other platforms, but follow the following instructions on Bela.
By passing the flag -Wl,--wrap=pthread_cond_init
to the compiler at linking time, the linker will replace all the calls to pthread_cond_init
with calls to __wrap_pthread_create
*
. The Xenomai libs will provide an implementation for __wrap_pthread_cond_init()
(and many other Posix functions!), so that an appropriately linked program (or library )will use those instead of the regular ones **
.
In practice you have to add one of those entries for each function for which you want to use the Xenomai implementation, e.g.:
-Wl,--wrap=pthread_cond_create -Wl,--wrap=pthread_cond_destroy -Wl,--wrap=pthread_cond_timedwait -Wl,--wrap=pthread_cond_signal
***
.
An alternative approach to using linking-time symbol wrapping, is to manually call the __wrap_
function from your code where appropriate. This approach is the one that allows you to use the Xenomai implementation only for some of the calls to a given function.
You can #ifdef
this, and/or use some clever (and to me obscure) C-preprocessor syntax as appropriate. You'd have to add -I/usr/xenomai/include
to the compiler flags, so that when you#include <posix.h>
it loads /usr/xenomai/include/posix.h
which contains the forward declarations for the __wrap_
functions ****
.
Additionally to the above (whichever approach you chose), you have to include the Xenomai libraries, The appropriate flags are given by running:
$ /usr/xenomai/bin/xeno-config --skin=cobalt --no-auto-init --no-mode-check --ldflags
which returns:
-Wl,--no-as-needed -L/usr/xenomai/lib -lcobalt -lmodechk -lpthread -lrt
Just add this and the string you crafted above to the linker stage and you should be sorted *****
.
*
it also replaces the calls to __real_pthread_create
with calls to pthread_create
, but this is not relevant for us just now.
**
Xenomai provides an automated method to wrap all the calls to any Posix function for which it provides an implementation , however that has some problems when used with C++, and also I think it is better to only wrap those you want. A full list of all the wrappable functions is in /usr/xenomai/lib/cobalt.wrappers
.
***
Alternatively, you can pass a file containing all the flags for the functions you want to wrap (modelled on /usr/xenomai/lib/cobalt.wrappers
) by doing: -Wl,@/path/to/your/custom/file.wrappers
.
****
or you can forward-declare them yourself, as we do in include/xenomai_wraps.h
.
*****
unless you see that your external is not loaded, ping me if that is the case.