A) Am I right, both about being bad, and about clock
pre-allocation and pooling being a decent solution?
B) Does anyone have tips on how one should implement and use
said clock pool?
ad A), basically yes, but in Pd you can get away with it. Pd's
scheduler doesn't run in the actual audio callback (unless you
run Pd in "callback" mode) and is more tolerant towards
operations that are not exactly realtime friendly (e.g. memory
allocation, file IO, firing lots of messages, etc.). The audio
callback and scheduler thread exchange audio samples via a
lockfree ringbuffer. The "delay" parameter actually sets the size
of this ringbuffer, and a larger size allows for larger CPU spikes.
In practice, allocating a small struct is pretty fast even with
the standard memory allocator, so in the case of Pd it's nothing
to worry about. In Pd land, external authors don't really care
too much about realtime safety, simply because Pd itself doesn't
either.
---
Now, in SuperCollider things are different. Scsynth and Supernova
are quite strict regarding realtime safety because DSP runs in
the audio callback. In fact, they use a special realtime
allocator in case a plugin needs to allocate memory in the audio
thread. Supercollider also has a seperate non-realtime thread
where you would execute asynchronous commands, like loading a
soundfile into a buffer.
Finally, all sequencing and scheduling runs in a different
program (sclang). Sclang sends OSC bundles to scsynth, with
timestamps in the near future. Conceptually, this is a bit
similar to Pd's ringbuffer scheduler, with the difference that
DSP itself never blocks. If Sclang blocks, OSC messages will
simply arrive late at the Server.
Christof
On 25.10.2020 02:10, Iain Duncan wrote:
Hi folks, I'm working on an external for Max and PD embedding
the S7 scheme interpreter. It's mostly intended to do things at
event level, (algo comp, etc) so I have been somewhat lazy
around real time issues so far. But I'd like to make sure it's
as robust as it can be, and can be used for as much as possible.
Right now, I'm pretty sure I'm being a bad real-time-coder. When
the user wants to delay a function call, ie (delay 100
foo-fun), I'm doing the following:
- callable foo-fun gets registered in a scheme hashtable with a
gensym unique handle
- C function gets called with the handle
- C code makes a clock, storing it in a hashtable (in C) by the
handle, and passing it a struct (I call it the "clock callback
info struct") with the references it needs for it's callback
- when the clock callback fires, it gets passed a void pointer
to the clock-callback-info-struct, uses it to get the cb handle
and the ref to the external (because the callback only gets one
arg), calls back into Scheme with said handle
- Scheme gets the callback out of it's registry and executes the
stashed function
This is working well, but.... I am both allocating and
deallocating memory in those functions: for the clock, and for
the info struct I use to pass around the reference to the
external and the handle. Given that I want to be treating this
code as high priority, and having it execute as timing-accurate
as possible, I assume I should not be allocating and freeing in
those functions, because I could get blocked on the memory
calls, correct? I think I should probably have a pre-allocated
pool of clocks and their associated info structs so that when a
delay call comes in, we get one from the pool, and only do
memory management if the pool is empty. (and allow the user to
set some reasonable config value of the clock pool). I'm
thinking RAM is cheap, clocks are small, people aren't likely to
have more than 1000 delay functions running concurrently or
something at once, and they can be allocated from the init routine.
My questions:
A) Am I right, both about being bad, and about clock
pre-allocation and pooling being a decent solution?
B) Does anyone have tips on how one should implement and use
said clock pool?
I suppose I should probably also be ensuring the Scheme
hash-table doesn't do any unplanned allocation too, but I can
bug folks on the S7 mailing list for that one...
Thanks!
iain
_______________________________________________
Pd-dev mailing list
[email protected] <mailto:[email protected]>
https://lists.puredata.info/listinfo/pd-dev
<https://lists.puredata.info/listinfo/pd-dev>
_______________________________________________
Pd-dev mailing list
[email protected] <mailto:[email protected]>
https://lists.puredata.info/listinfo/pd-dev
<https://lists.puredata.info/listinfo/pd-dev>