Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

call_ret without heap allocations? #748

Open
obsoleszenz opened this issue Mar 4, 2024 · 3 comments
Open

call_ret without heap allocations? #748

obsoleszenz opened this issue Mar 4, 2024 · 3 comments

Comments

@obsoleszenz
Copy link

I'm currently evaluating if dyon is suitable to use as a scripting language in a soft realtime environment (audio dsp).
I'm building equis, a software dj mixer and i want it to have midi mappings, so that one can write a little script that maps incoming midi messages from a hardware controller to the neccessairy dsp parameter changes.

What I want to achieve is, that those scripts can be run in the audio realtime thread/callback, which is a soft realtime environment and therefore heap allocations should not happen.

I built a small PoC with dyon (https://codeberg.org/obsoleszenz/EQUIS/pulls/26) and was able to call a simple fn on_midi() ~ mut state method and assert_no_alloc didn't complain. But as soon as I'm trying to add a RustObject or Array variable as a parameter to the method, some allocations (maybe clones? maybe Box::new?) are happening. I looked a bit into the code and was the runtime.module is getting cloned and swapped.

So now my question, would it be possible to make dyons call() path so that it doesn't do/need heap allocations?

Btw thanks a lot for dyon, a borrowchecked/typed scripting language is amazing!

@bvssvni
Copy link
Member

bvssvni commented Mar 4, 2024

I also experimented with audio and added grab support at top level to allow pre-allocation of data such as arrays.

E.g.

fn main() {
    data := grab [1, 2, 3, 4, ...]
    ...
}

Is this a feature that you are looking for?

@bvssvni
Copy link
Member

bvssvni commented Mar 4, 2024

I haven't looked into the cloning of the runtime module. Do you have an idea of where in the Dyon codebase this is caused?

@obsoleszenz
Copy link
Author

I also experimented with audio and added grab support at top level to allow pre-allocation of data such as arrays.

E.g.

fn main() {
    data := grab [1, 2, 3, 4, ...]
    ...
}

Is this a feature that you are looking for?

Didn't know about grab, that looks useful :)

I haven't looked into the cloning of the runtime module. Do you have an idea of where in the Dyon codebase this is caused?

I looked again and i think it should be fine as it's just an Arc that is getting cloned. I will have to look again into it. But I found another way, I'm now passing in the midi message as a vec4 which works well.

In fact I can now do this which is already quite helpful:

fn init_state() ~ mut state {
    state.counter := 0
    state.name := "Test"
}

fn on_midi(midi_in: vec4) ~ mut state {
    state.counter += 1

    status := x(midi_in)
    channel := y(midi_in)
    note := z(midi_in)
    value := w(midi_in)
    value_normalized := value / 127.0

    if note == 1 {
        dsp_set(ID_VOLUME_CH0() + channel, value_normalized)
    } else if note == 2 {
        dsp_set(ID_GAIN_CH0() + channel, value_normalized)
    }
    // Todo:
    // send_midi(0xB1, 12, dsp_get(ID_DB_METER_CH0()) * 127.0)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants