Some background
I'm working on building a programming language for digital media programming, which should support concurrency using no-sharing message passing and soft real-time (i.e. do your best to compute audio/video without losing samples or frames and with a constant throughput).
It turns out that both these features are surprisingly difficult to combine, mainly because of one particular constraint: real-time code should not dynamically allocate memory.
My language should make it easy to implement something like this:
- One thread computes audio samples based on parameters. These can be, for example, the values of different controls of a synthesizers. This thread runs "in real time".
- One thread receives input from the user or from another computer to change those values. This could be the GUI thread, for instance, reacting to the user turning in a knob with the mouse.
I want the new values set by the user to be sent through a queue to the synthesizer engine. Now the problem would not be interesting if I only wanted to send floats and other atomic values. Actually, I want any kind of data to be able to flow from one thread to another, even a complex object or a data structure, and this should be possible for any configuration of threads and priorities. Without dynamic memory allocation on the real-time side, this becomes very difficult without imposing what seems like arbitrary restrictions on the programmer.
Erlang is often advertized as a good fit for real-time systems. My understanding is that Erlang does never, however, disallow memory allocation. If I did the same, it would make lots of problems go away, at the cost of introducing non-deterministic timing in the code that performs those allocation.
The question
So what makes Erlang such a good fit? Does it implement special tricks to circumvent the problems induced by memory allocation, or does it ignore the problem entirely? Does it take another approach to real-time?
An example to illustrate the question
Let's assume that we're writing a synthesizer in Erlang, which has to produce 64 samples every 50 milliseconds, otherwise there's cracks and pops in the sound. Let's assume also that when I move some slider around on the string, a small object (let's say it's a list or a tuple containing the parameter's name and new value) has to be sent out from the GUI process to the audio process, where a copy is created. This would requrie dynamic memory allocation. How would Erlang help me make sure that this allocation does not delay my audio computation?