Skip to content

Commit

Permalink
Add 'Memory allocation issues' section in Rust documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
sletz committed Apr 13, 2024
1 parent e58ce13 commit 58315f9
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 3 deletions.
4 changes: 2 additions & 2 deletions architecture/faust/gui/APIUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ class APIUI : public PathBuilder, public Meta, public UI
int id4 = getZoneIndex(table, p, val);
if (id4 != -1) {
// Reactivate the one we edit...
table[val][uint(id4)]->setMappingValues(curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax);
table[val][uint(id4)]->setActive(true);
table[val][uint(id4)]->setMappingValues(curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax);
table[val][uint(id4)]->setActive(true);
} else {
// Allocate a new CurveZoneControl which is 'active' by default
FAUSTFLOAT* zone = fItems[uint(p)].fZone;
Expand Down
4 changes: 3 additions & 1 deletion architecture/faust/gui/ValueConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
(GRAME, Copyright 2015-2019)
Set of conversion objects used to map user interface values (for example a gui slider
delivering values between 0 and 1) to faust values (for example a vslider between
delivering values between 0 and 1) to Faust values (for example a vslider between
20 and 20000) using a log scale.
-- Utilities
Expand Down Expand Up @@ -494,10 +494,12 @@ class FAUST_API CurveZoneControl : public ZoneControl {
fValueConverters.push_back(new AccDownUpConverter(amin, amid, amax, min, init, max));
fCurve = curve;
}

virtual ~CurveZoneControl()
{
for (const auto& it : fValueConverters) { delete it; }
}

void update(double v) const { if (fValueConverters[fCurve]->getActive()) *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v)); }

void setMappingValues(int curve, double amin, double amid, double amax, double min, double init, double max)
Expand Down
23 changes: 23 additions & 0 deletions architecture/rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,26 @@ Here are the available options:
By default, it will create a `file-jackrust` folder with the Rust project and compile it using cargo.

As usual with faust2xx tools, other Faust compiler specific options can be given to **faust2portaudiorust**, like `-vec -lv 1` to compile in vector mode.etc.

## Memory allocation issues

At the moment, there is no formal way to allocate an arbitrary struct on the heap in rust. The current approach taken by Faust is to allocate the dsp with `Box::new(Dsp::new())` which would be expected to first allocate on stack then move on heap, but this move is optimized away in release and it's allocated directly on the heap. However, when running in debug mode, the intermediary allocation is here making any echo or reverb very likely to stack overflow.

The standard way is to allocate the DSP on the heap with the help of the third-party `crate default-boxed`.

The change in the generated code of Faust is very conservative: it's under conditional compilation with a feature, disabled by default. When the feature is enabled, it adds a `new default_boxed()` method. This change should not break any user, including in specific environment such as embedded/no-std. The following code can be used to setup the allocation:

```Rust
let mut dsp;
#[cfg(feature = "default-boxed")]
{
use default_boxed::DefaultBoxed;
dsp = mydsp::default_boxed();
}

#[cfg(not(feature = "default-boxed"))]
{
dsp = Box::new(mydsp::new());
}
```

0 comments on commit 58315f9

Please sign in to comment.