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/

Reply via email to