Sure. I guess I don't know what I'm saying :D other than the question: what do we reasonably need? Does the current solution work or is the next step required?
On May 22, 2014, at 5:03 PM, pd-dev-request@lists.iem.at wrote:
To me, I think the ultimate use case is to be able to fire up two versions of pd in the same processing chain (take vst's in a DAW for example), load each one with identical patches, and have them controlled separately. This would be a fantastic boost for the ability to extend what we can already do with Pd as an audio processing engine, separated from its native GUI. Locking may be necessary in places, but then that is extremely fast these days.
Of course, this all leads to the pdinstance being able to manage the symbol table along with Miller's recent changes, but what are the difficulties in achieving this? It seems like Miller tried and it was more difficult than what we are imagining.
cheers, Rich
-------- Dan Wilcox @danomatika danomatika.com robotcowboy.com
Hi everybody, Sorry to chime in so late in the conversation...
Here's my take on the discussion so far:
1. I'm thrilled to see that multiple instances are happening. Thanks, Miller!
2. If at all possible, we should go all the way and have fully independent instances. Anything else will likely come back to bite us, by requiring additional documentation and other support, confusing developers (and therefore giving rise to bugs), underutilizing multicore systems, excluding use cases that we haven't thought of yet, etc. (And I already have a few use cases where concurrent instances would have been handy.)
3. As I understand the current state, there are two problems that we need to solve to achieve independent instances. One is a revision of the API to introduce an additional instance parameter. That might be unpleasant to implement but seems feasible. (I always expected that we'd need a completely revised libpd 2.0 when multiple instances become available.) The other one is the shared symbol table.
4. Miller, you said in your original post that you ran into seemingly insoluble problems when trying to create per-instance symbol tables. Would you mind elaborating on this point?
5. Even if we're stuck with a single global symbol table, we may be able to make it thread-safe without having to resort to locks.
Cheers, Peter
On Thu, May 22, 2014 at 5:24 PM, Dan Wilcox danomatika@gmail.com wrote:
Sure. I guess I don't know what I'm saying :D other than the question: what do we reasonably need? Does the current solution work or is the next step required?
On May 22, 2014, at 5:03 PM, pd-dev-request@lists.iem.at wrote:
To me, I think the ultimate use case is to be able to fire up two versions of pd in the same processing chain (take vst's in a DAW for example), load each one with identical patches, and have them controlled separately. This would be a fantastic boost for the ability to extend what we can already do with Pd as an audio processing engine, separated from its native GUI. Locking may be necessary in places, but then that is extremely fast these days.
Of course, this all leads to the pdinstance being able to manage the symbol table along with Miller's recent changes, but what are the difficulties in achieving this? It seems like Miller tried and it was more difficult than what we are imagining.
cheers, Rich
Dan Wilcox @danomatika danomatika.com robotcowboy.com
Pd-dev mailing list Pd-dev@lists.iem.at http://lists.puredata.info/listinfo/pd-dev
Short answer: I started discovering that there were static structures in Pd that had ponters to symbols - all such static structures would have to be tracked down and made per-instance.
Longer one:
The specific one I hit (but this could be only one of many problems hiding there) was every single static t_class (one per class). This structure containes a list of symbols (message selectors) and associated function pointers (and more).
At first I thought, no problem, we'll just create one trigger_class (e.g.) per Pd nstance by calling all the init methds anew for each new Pd instance. But that failed miserably because:
t_trgger *x = pd_new(trgger_class)
then blithely picks up the most recently created trgger_class and not the instance-specfc one. That new one then can't find any messages because it has teh symbols fro mteh wrong PD instance to check against.
I thought of perhaps changing the class structure itself to keep track of which instance we're in, but couldn't fgure out how to do it without requiring a hash list lookup on each message pass in Pd (ugh) or by making incompatible API changes.
And this might just be the tip of an iceberg - I have no idea what other oopses I'd discover after coding all that up.
cheers M
On Sun, May 25, 2014 at 11:42:07PM -0400, Peter Brinkmann wrote:
Hi everybody, Sorry to chime in so late in the conversation...
Here's my take on the discussion so far:
- I'm thrilled to see that multiple instances are happening. Thanks,
Miller!
- If at all possible, we should go all the way and have fully independent
instances. Anything else will likely come back to bite us, by requiring additional documentation and other support, confusing developers (and therefore giving rise to bugs), underutilizing multicore systems, excluding use cases that we haven't thought of yet, etc. (And I already have a few use cases where concurrent instances would have been handy.)
- As I understand the current state, there are two problems that we need
to solve to achieve independent instances. One is a revision of the API to introduce an additional instance parameter. That might be unpleasant to implement but seems feasible. (I always expected that we'd need a completely revised libpd 2.0 when multiple instances become available.) The other one is the shared symbol table.
- Miller, you said in your original post that you ran into seemingly
insoluble problems when trying to create per-instance symbol tables. Would you mind elaborating on this point?
- Even if we're stuck with a single global symbol table, we may be able to
make it thread-safe without having to resort to locks.
Cheers, Peter
On Thu, May 22, 2014 at 5:24 PM, Dan Wilcox danomatika@gmail.com wrote:
Sure. I guess I don't know what I'm saying :D other than the question: what do we reasonably need? Does the current solution work or is the next step required?
On May 22, 2014, at 5:03 PM, pd-dev-request@lists.iem.at wrote:
To me, I think the ultimate use case is to be able to fire up two versions of pd in the same processing chain (take vst's in a DAW for example), load each one with identical patches, and have them controlled separately. This would be a fantastic boost for the ability to extend what we can already do with Pd as an audio processing engine, separated from its native GUI. Locking may be necessary in places, but then that is extremely fast these days.
Of course, this all leads to the pdinstance being able to manage the symbol table along with Miller's recent changes, but what are the difficulties in achieving this? It seems like Miller tried and it was more difficult than what we are imagining.
cheers, Rich
Dan Wilcox @danomatika danomatika.com robotcowboy.com
Pd-dev mailing list Pd-dev@lists.iem.at http://lists.puredata.info/listinfo/pd-dev
Pd-dev mailing list Pd-dev@lists.iem.at http://lists.puredata.info/listinfo/pd-dev
Thanks for the informative read.
On Mon, May 26, 2014 at 1:47 PM, Miller Puckette msp@ucsd.edu wrote:
Short answer: I started discovering that there were static structures in Pd that had ponters to symbols - all such static structures would have to be tracked down and made per-instance.
Longer one:
The specific one I hit (but this could be only one of many problems hiding there) was every single static t_class (one per class). This structure containes a list of symbols (message selectors) and associated function pointers (and more).
These are class-level selectors and function pointers only, no? It seems like an acceptable limitation to me that symbols relative to a static class definition be unique across the memory space. There is a similar limitation in the obj-c runtime, not nice but that's just part of the language.
The part that seems like it would cause a great deal of confusion would be things like send and receiver names, table names, etc. How difficult is it to make these per-instance and deal with classes as static objects that need to use sys_lock() to ensure thread safety? I realize this may not suit every use case, but it seems like this would still greatly improve the feasibility of using pd as a plug-in.
As a second alternative, I was wondering if it isn't possible to prepend a unique per-instance arg to symbols like the ones mentioned above. Of course has threading issues that would need to be resolved...
cheers, Rich
Hi Rich -
These are class-level selectors and function pointers only, no? It seems like an acceptable limitation to me that symbols relative to a static class definition be unique across the memory space. There is a similar limitation in the obj-c runtime, not nice but that's just part of the language.
The part that seems like it would cause a great deal of confusion would be things like send and receiver names, table names, etc. How difficult is it to make these per-instance and deal with classes as static objects that need to use sys_lock() to ensure thread safety? I realize this may not suit every use case, but it seems like this would still greatly improve the feasibility of using pd as a plug-in.
I think this won't work - if you have duplicate symbols flying around in the same instance for the same strings someone will test s1 == s2 somewhere and fail to see a match. I don't think it's feasible to have two symbol types, one for selectors and another for all other names, because you never know when a symbol is being created which of the two it's going to be.
As a second alternative, I was wondering if it isn't possible to prepend a unique per-instance arg to symbols like the ones mentioned above. Of course has threading issues that would need to be resolved...
This is an interesting possibility. I found 48 calls to pd_bind() so presumably I'd have to make 48 edits to prepend a string to every symbol that anything binds itself to. The tricker thing would be message boxes - binbuf_eval() would probably have to do the same prepending when passing messages to named objects from message boxes. (Unless we were just to blow that off and require using explicit "send" objects instead which you'd have to do anyway as it is now, since everything now has to be "$0" - protected.)
cheers Miller