Hi Miller,
first off, the Pd desktop app is not single-threaded. By default, Pd has
at least two threads: the audio callback and the main thread. Portmidi
uses threads internally for sending and receiving MIDI. Every [readsf~]
and [writesf~] object spawns another thread. Etc.
In general, it's not really practical to have a modern desktop
application that only uses a single thread.
The Pd *core* can indeed run in a single threaded environment and that's
a good thing. However, IMO this doesn't mean that Pd should not utilize
multiple threads. For example, see my proposed task API:
https://github.com/pure-data/pure-data/pull/1357. This is also a good
example for *safe* multi-threading because it avoids mutable shared data
in favor of message passing.
---
That being said, this discussion is not really about threads in Pd.
(PDINSTANCE does not necessarily imply multi-threading: there are many
use cases for multiple Pd instances that are *not* computed in
parallel.) The question is whether externals should be compiled with
PDINSTANCE by default.
Ideally, externals should not have to care if they run in a
single-instance or multi-instance environment. In fact, this is already
the case as long the external only calls API functions. The problem lies
in the global symbols "s_float", "s_symbol", etc. These are pretty much
the only reason why we need the PDINSTANCE macro in the first place.
We can't really compile the standalone Pd with PDINSTANCE because it
would break existing externals that use the global symbols.
However, the solution is pretty simple: if an external should work in
both environments, it simply should avoid the global symbols. In that
case, it simply doesn't matter if it's compiled with PDINSTANCE or not.
We should probably start updating existing externals by replacing the
global symbols with gensym() calls. To simplify this process, we could
add a macro that hides the global symbols, so we can easily detect
externals that make use of them.
---
There is still the edge case with worker threads that need to set the Pd
instance. That's why I have suggested to unconditionally export
pd_setinstance() and pd_getinstance().
Christof
On 7/3/2026 4:29 PM, Miller Puckette via Pd-dev wrote:
I'm no expert on threads but... I think it's important to keep the Pd
app single-threaded for two reasons - first because I've never seen a
multi-threaded application that doesn't occasionally crash because of
some hidden failure to maintain thread safety, for instance in some
library that's being used. Second, because Pd needs to be able to run
in environments such as DSP processors where posix threads aren't
necessarily available.
Perhaps it's possible to define PDINSTANCE without breaking external
binary compatibility, but I'm not sure of that either.
cheers
Miller
On 6/29/26 6:43 PM, Antoine Rousseau wrote:
by "removing PDINSTANCE/PDTHREADSflags", I just meant that if the
single-context code is removed, and everything is unconditionally
compiled for multiple instances and threads, then the flags can be
removed as well.
Antoine
Le lun. 29 juin 2026 à 18:34, Antoine Rousseau <[email protected]> a
écrit :
I meant, in the end, compile everything (Pd, libpd and externals)
with PDINSTANCE/PDTHREADS and give up specific single thread code.
Of course this won't magically make every external suitable for
multiple threads of contexts...
But at least there will be only one binary interface.
Antoine
Le lun. 29 juin 2026 à 17:13, IOhannes m zmölnig via Pd-dev
<[email protected]> a écrit :
On 29/06/2026 14:30, Antoine Rousseau wrote:
> However, I have wondered whether it might be possible, in
the future, to
> achieve a convergence between multiple-instance and
single-instance code.
> That is: always compile libpd with PDINSTANCE/PDTHREADS
flags (then just
> remove them), and the same for Pd. I think the overhead is
negligible.
>
my thoughts (about convergence).
though i don't know what exactly you mean with:
> always compile libpd with PDINSTANCE/PDTHREADS flags (then
just
> remove them)
something like: compile libpd (and eventually Pd itself?) with
PDINSTANCE/PDTHREADS, but allow externals to be compiled
without these
flags?
that probably wouldn't allow for the externals to be used in a
multi-context/multi-threaded runtime, but at least it would be
possible
to use them in single-context mode by a multi-context
*capable* runtime.
i guess this is something i would like to have as an
intermediate step
(until all externals are multi-context capable).
one question is of course, which class of hard-to-find bugs
this would
open up.
gmdsar
IOhannes
---
[email protected] - the Pd developers' mailinglist
https://lists.iem.at/hyperkitty/list/[email protected]/message/IJUWCSPL25Q7XBX4AZX6GN7IUNIMKVEK/
<https://urldefense.com/v3/__https://lists.iem.at/hyperkitty/list/[email protected]/message/IJUWCSPL25Q7XBX4AZX6GN7IUNIMKVEK/__;!!Mih3wA!A5zGIo_qhc2DMTFCnmlnhiQAN7jZQTyj5fcrNSZHXkf_JpSYR1CcbLbJBSJTk1h-PhogXuJJ0veq$>
---
[email protected] - the Pd developers' mailinglist
https://urldefense.com/v3/__https://lists.iem.at/hyperkitty/list/[email protected]/message/75RB7A36TMJ6NCGBOQ7EDVK36QXJLNRF/__;!!Mih3wA!A5zGIo_qhc2DMTFCnmlnhiQAN7jZQTyj5fcrNSZHXkf_JpSYR1CcbLbJBSJTk1h-PhogXjlD8_qP$
---
[email protected] - the Pd developers' mailinglist
https://lists.iem.at/hyperkitty/list/[email protected]/message/K6RHP5H63FADSPLQNNKKMDXPWDYSVQU7/
---
[email protected] - the Pd developers' mailinglist
https://lists.iem.at/hyperkitty/list/[email protected]/message/WP2MEXNUSMX7KIZUIEJWQB7VA32556TS/