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

Memory management improvements #638

Merged
merged 20 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7bdd7f1
Improved memory full reporting to include other areas
PaulFreund Oct 18, 2023
208a513
Simplified MemoryRegion and added more error checking, might even sol…
PaulFreund Oct 20, 2023
72254f3
Made GMA API much more intentional wich different alloc functions and…
PaulFreund Oct 20, 2023
0f1e600
Fixed check for proper spacing
PaulFreund Oct 20, 2023
feaa3a9
Fixed memory region and tests
PaulFreund Oct 20, 2023
5e2b3d0
Minor fixes
PaulFreund Oct 22, 2023
c3d73a7
Changes as done in meeting
PaulFreund Oct 22, 2023
fee6bbc
Removed allocStealableMaxSpeed
PaulFreund Oct 22, 2023
02de5cb
alloc powers of 2 and minimum size
m-m-adams Oct 22, 2023
d904671
alignment, padding, sorting
m-m-adams Oct 22, 2023
2aa471a
update tests
m-m-adams Oct 23, 2023
b1fbf53
Merge branch 'memory_fragmentation' into bugfix/huntingMemoryProblems
m-m-adams Oct 23, 2023
26e3e18
update tests and fix merge issues
m-m-adams Oct 23, 2023
ae624a1
dbt format
m-m-adams Oct 23, 2023
1e3c15e
Move allocations into the most reasonable memory locations
PaulFreund Oct 23, 2023
bfd3821
Renamed external to stealable, and nonaudio to external and made sure…
PaulFreund Oct 23, 2023
fecacd8
Merge branch 'bugfix/huntingMemoryProblems' of https://github.com/Syn…
PaulFreund Oct 23, 2023
c44294e
Moved params back to internal memory
PaulFreund Oct 23, 2023
81c3b27
Merge remote-tracking branch 'upstream/release/1.0' into bugfix/hunti…
PaulFreund Oct 24, 2023
d86ca85
Removed v7_dma_flush_range for now
PaulFreund Oct 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions contrib/debug/heap_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,9 @@ def parse_memory_region(inferior, offset, mem_region_idx):
)

MEM_REGION_NAMES = [
"EXTERNAL",
"STEALABLE",
"INTERNAL",
"NONAUDIO",
"EXTERNAL",
]
mem_region_name = MEM_REGION_NAMES[mem_region_idx]

Expand Down Expand Up @@ -425,18 +425,18 @@ def parse_gma(inferior=gdb.inferiors()[0]):
if HEAP_START is not None:
EXTERNAL_MEMORY_START = 0x0C000000
EXTERNAL_MEMORY_END = 0x10000000
RESERVED_NONAUDIO_ALLOCATOR = 0x00100000
RESERVED_EXTERNAL_ALLOCATOR = 0x00100000

print("** External heap blocks:")
print("** Stealable heap blocks:")
parse_heap(
inferior,
EXTERNAL_MEMORY_START,
EXTERNAL_MEMORY_END - RESERVED_NONAUDIO_ALLOCATOR,
EXTERNAL_MEMORY_END - RESERVED_EXTERNAL_ALLOCATOR,
)
print("** Nonaudio heap blocks:")
print("** External heap blocks:")
parse_heap(
inferior,
EXTERNAL_MEMORY_END - RESERVED_NONAUDIO_ALLOCATOR,
EXTERNAL_MEMORY_END - RESERVED_EXTERNAL_ALLOCATOR,
EXTERNAL_MEMORY_END,
)
print("** Internal Heap blocks:")
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/deluge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ void setUIForLoadedSong(Song* song) {
}

void setupBlankSong() {
void* songMemory = GeneralMemoryAllocator::get().alloc(sizeof(Song), NULL, false, true); // TODO: error checking
void* songMemory = GeneralMemoryAllocator::get().allocMaxSpeed(sizeof(Song)); // TODO: error checking
preLoadedSong = new (songMemory) Song();

preLoadedSong->paramManager.setupUnpatched(); // TODO: error checking
Expand Down
3 changes: 2 additions & 1 deletion src/deluge/drivers/uart/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ int32_t uartFlush(int32_t item) {
DMACn(txDmaChannels[item]).N0TB_n = num;
uint32_t dataAddress = (uint32_t)&txBuffers[item][prevReadPos];
DMACn(txDmaChannels[item]).N0SA_n = dataAddress;
v7_dma_flush_range(dataAddress, dataAddress + num);
// Paul: Removed from now as this was not present before and I am unsure if it helps with anything
// v7_dma_flush_range(dataAddress, dataAddress + num);

return 1;
}
Expand Down
3 changes: 1 addition & 2 deletions src/deluge/dsp/delay/delay_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ uint8_t DelayBuffer::init(uint32_t newRate, uint32_t failIfThisSize, bool includ
sizeIncludingExtra = size + (includeExtraSpace ? delaySpaceBetweenReadAndWrite : 0);
AudioEngine::logAction("DelayBuffer::init before");

bufferStart = (StereoSample*)GeneralMemoryAllocator::get().alloc(sizeIncludingExtra * sizeof(StereoSample), NULL,
false, true);
bufferStart = (StereoSample*)GeneralMemoryAllocator::get().allocLowSpeed(sizeIncludingExtra * sizeof(StereoSample));
AudioEngine::logAction("DelayBuffer::init after");
if (bufferStart == 0) {
return ERROR_INSUFFICIENT_RAM;
Expand Down
4 changes: 2 additions & 2 deletions src/deluge/dsp/timestretch/time_stretcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,8 +1049,8 @@ void TimeStretcher::reassessWhetherToBeFillingBuffer(int32_t phaseIncrement, int
#endif

bool TimeStretcher::allocateBuffer(int32_t numChannels) {
buffer = (int32_t*)GeneralMemoryAllocator::get().alloc(TimeStretch::kBufferSize * sizeof(int32_t) * numChannels,
NULL, false, true);
buffer =
(int32_t*)GeneralMemoryAllocator::get().allocMaxSpeed(TimeStretch::kBufferSize * sizeof(int32_t) * numChannels);
return (buffer != NULL);
}

Expand Down
2 changes: 1 addition & 1 deletion src/deluge/gui/context_menu/clear_song.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ bool ClearSong::acceptCurrentOption() {
AudioEngine::songSwapAboutToHappen();
}

void* songMemory = GeneralMemoryAllocator::get().alloc(sizeof(Song), NULL, false, true); // TODO: error checking
void* songMemory = GeneralMemoryAllocator::get().allocMaxSpeed(sizeof(Song)); // TODO: error checking
preLoadedSong = new (songMemory) Song();
preLoadedSong->paramManager.setupUnpatched(); // TODO: error checking
GlobalEffectable::initParams(&preLoadedSong->paramManager);
Expand Down
5 changes: 2 additions & 3 deletions src/deluge/gui/ui/browser/sample_browser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1317,8 +1317,7 @@ bool SampleBrowser::loadAllSamplesInFolder(bool detectPitch, int32_t* getNumSamp
// If all samples were tagged with the same MIDI note, we get suspicious and delete them.
bool discardingMIDINoteFromFile = (numSamples > 1 && commonMIDINote >= 0);

Sample** sortArea =
(Sample**)GeneralMemoryAllocator::get().alloc(numSamples * sizeof(Sample*) * 2, NULL, false, true);
Sample** sortArea = (Sample**)GeneralMemoryAllocator::get().allocMaxSpeed(numSamples * sizeof(Sample*) * 2);
if (!sortArea) {
error = ERROR_INSUFFICIENT_RAM;
goto removeReasonsFromSamplesAndGetOut;
Expand Down Expand Up @@ -1919,7 +1918,7 @@ bool SampleBrowser::importFolderAsKit() {
goto getOut;
}

void* drumMemory = GeneralMemoryAllocator::get().alloc(sizeof(SoundDrum), NULL, false, true);
void* drumMemory = GeneralMemoryAllocator::get().allocMaxSpeed(sizeof(SoundDrum));
if (!drumMemory) {
goto getOut;
}
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/gui/ui/load/load_song_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ void LoadSongUI::performLoad() {
playbackHandler.songSwapShouldPreserveTempo = Buttons::isButtonPressed(deluge::hid::button::TEMPO_ENC);
}

void* songMemory = GeneralMemoryAllocator::get().alloc(sizeof(Song), NULL, false, true);
void* songMemory = GeneralMemoryAllocator::get().allocMaxSpeed(sizeof(Song));
if (!songMemory) {
ramError:
error = ERROR_INSUFFICIENT_RAM;
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/gui/ui/slicer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ void Slicer::doSlice() {
goto getOut;
}

void* drumMemory = GeneralMemoryAllocator::get().alloc(sizeof(SoundDrum), NULL, false, true);
void* drumMemory = GeneralMemoryAllocator::get().allocMaxSpeed(sizeof(SoundDrum));
if (!drumMemory) {
ramError:
error = ERROR_INSUFFICIENT_RAM;
Expand Down
4 changes: 2 additions & 2 deletions src/deluge/gui/views/arranger_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1535,7 +1535,7 @@ void ArrangerView::editPadAction(int32_t x, int32_t y, bool on) {
int32_t size = (output->type == InstrumentType::AUDIO) ? sizeof(AudioClip)
: sizeof(InstrumentClip);

void* memory = GeneralMemoryAllocator::get().alloc(size, NULL, false, true);
void* memory = GeneralMemoryAllocator::get().allocMaxSpeed(size);
if (!memory) {
display->displayError(ERROR_INSUFFICIENT_RAM);
goto justGetOut;
Expand Down Expand Up @@ -2630,7 +2630,7 @@ ActionResult ArrangerView::horizontalEncoderAction(int32_t offset) {

if (offset >= 0) {
void* consMemory =
GeneralMemoryAllocator::get().alloc(sizeof(ConsequenceArrangerParamsTimeInserted));
GeneralMemoryAllocator::get().allocLowSpeed(sizeof(ConsequenceArrangerParamsTimeInserted));
if (consMemory) {
ConsequenceArrangerParamsTimeInserted* consequence = new (consMemory)
ConsequenceArrangerParamsTimeInserted(currentSong->xScroll[NAVIGATION_ARRANGEMENT],
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/gui/views/clip_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ ActionResult ClipView::horizontalEncoderAction(int32_t offset) {
action = actionLogger.getNewAction(ACTION_CLIP_HORIZONTAL_SHIFT, ACTION_ADDITION_NOT_ALLOWED);
if (action) {
addConsequenceToAction:
void* consMemory = GeneralMemoryAllocator::get().alloc(sizeof(ConsequenceClipHorizontalShift));
void* consMemory = GeneralMemoryAllocator::get().allocLowSpeed(sizeof(ConsequenceClipHorizontalShift));

if (consMemory) {
ConsequenceClipHorizontalShift* newConsequence =
Expand Down
17 changes: 9 additions & 8 deletions src/deluge/gui/views/instrument_clip_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -931,8 +931,8 @@ void InstrumentClipView::copyNotes() {
int32_t numNotes = endI - startI;

if (numNotes > 0) {

void* copiedNoteRowMemory = GeneralMemoryAllocator::get().alloc(sizeof(CopiedNoteRow), NULL, true);
// Paul: Might make sense to put these into Internal?
void* copiedNoteRowMemory = GeneralMemoryAllocator::get().allocLowSpeed(sizeof(CopiedNoteRow));
if (!copiedNoteRowMemory) {
ramError:
deleteCopiedNoteRows();
Expand All @@ -948,8 +948,8 @@ void InstrumentClipView::copyNotes() {
prevPointer = &newCopiedNoteRow->next;

// Allocate some memory for the notes
newCopiedNoteRow->notes =
(Note*)GeneralMemoryAllocator::get().alloc(sizeof(Note) * numNotes, NULL, true);
// Paul: Might make sense to put these into Internal?
newCopiedNoteRow->notes = (Note*)GeneralMemoryAllocator::get().allocLowSpeed(sizeof(Note) * numNotes);

if (!newCopiedNoteRow->notes) {
goto ramError;
Expand Down Expand Up @@ -1152,7 +1152,7 @@ void InstrumentClipView::doubleClipLengthAction() {
// Add the ConsequenceClipMultiply to the Action. This must happen before calling doubleClipLength(), which may add note changes and deletions,
// because when redoing, those have to happen after (and they'll have no effect at all, but who cares)
if (action) {
void* consMemory = GeneralMemoryAllocator::get().alloc(sizeof(ConsequenceInstrumentClipMultiply));
void* consMemory = GeneralMemoryAllocator::get().allocLowSpeed(sizeof(ConsequenceInstrumentClipMultiply));

if (consMemory) {
ConsequenceInstrumentClipMultiply* newConsequence = new (consMemory) ConsequenceInstrumentClipMultiply();
Expand Down Expand Up @@ -3397,7 +3397,7 @@ void InstrumentClipView::enterDrumCreator(ModelStackWithNoteRow* modelStack, boo
return;
}

void* memory = GeneralMemoryAllocator::get().alloc(sizeof(SoundDrum), NULL, false, true);
void* memory = GeneralMemoryAllocator::get().allocMaxSpeed(sizeof(SoundDrum));
if (!memory) {
error = ERROR_INSUFFICIENT_RAM;
goto doDisplayError;
Expand Down Expand Up @@ -5416,7 +5416,8 @@ void InstrumentClipView::rotateNoteRowHorizontally(ModelStackWithNoteRow* modelS
action = actionLogger.getNewAction(ACTION_NOTEROW_HORIZONTAL_SHIFT, ACTION_ADDITION_NOT_ALLOWED);
if (action) {
addConsequenceToAction:
void* consMemory = GeneralMemoryAllocator::get().alloc(sizeof(ConsequenceNoteRowHorizontalShift));
void* consMemory =
GeneralMemoryAllocator::get().allocLowSpeed(sizeof(ConsequenceNoteRowHorizontalShift));

if (consMemory) {
ConsequenceNoteRowHorizontalShift* newConsequence =
Expand Down Expand Up @@ -5532,7 +5533,7 @@ void InstrumentClipView::editNoteRowLength(ModelStackWithNoteRow* modelStack, in
return;
}

void* consMemory = GeneralMemoryAllocator::get().alloc(sizeof(ConsequenceNoteRowLength));
void* consMemory = GeneralMemoryAllocator::get().allocLowSpeed(sizeof(ConsequenceNoteRowLength));
if (!consMemory) {
goto ramError;
}
Expand Down
6 changes: 3 additions & 3 deletions src/deluge/gui/views/session_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1525,7 +1525,7 @@ static float lastColour = 192 - colourStep + 1;
Clip* SessionView::createNewInstrumentClip(int32_t yDisplay) {
actionLogger.deleteAllLogs();

void* memory = GeneralMemoryAllocator::get().alloc(sizeof(InstrumentClip), NULL, false, true);
void* memory = GeneralMemoryAllocator::get().allocMaxSpeed(sizeof(InstrumentClip));
if (memory == nullptr) {
display->displayError(ERROR_INSUFFICIENT_RAM);
return nullptr;
Expand Down Expand Up @@ -1621,7 +1621,7 @@ void SessionView::replaceAudioClipWithInstrumentClip(Clip* clip, InstrumentType
}

// Allocate memory for InstrumentClip
void* clipMemory = GeneralMemoryAllocator::get().alloc(sizeof(InstrumentClip), NULL, false, true);
void* clipMemory = GeneralMemoryAllocator::get().allocMaxSpeed(sizeof(InstrumentClip));
if (!clipMemory) {
ramError:
display->displayError(ERROR_INSUFFICIENT_RAM);
Expand Down Expand Up @@ -3234,7 +3234,7 @@ bool SessionView::gridCreateNewTrackForClip(InstrumentType type, InstrumentClip*

InstrumentClip* SessionView::gridCreateClipWithNewTrack(InstrumentType type) {
// Allocate new clip
void* memory = GeneralMemoryAllocator::get().alloc(sizeof(InstrumentClip), NULL, false, true);
void* memory = GeneralMemoryAllocator::get().allocMaxSpeed(sizeof(InstrumentClip));
if (!memory) {
display->displayError(ERROR_INSUFFICIENT_RAM);
return nullptr;
Expand Down
12 changes: 8 additions & 4 deletions src/deluge/hid/display/seven_segment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ void SevenSegment::removeTopLayer() {
void SevenSegment::setText(std::string_view newText, bool alignRight, uint8_t drawDot, bool doBlink,
uint8_t* newBlinkMask, bool blinkImmediately, bool shouldBlinkFast, int32_t scrollPos,
uint8_t* encodedAddition, bool justReplaceBottomLayer) {
void* layerSpace = GeneralMemoryAllocator::get().alloc(sizeof(NumericLayerBasicText));
// Paul: Render time could be lower putting this into internal
void* layerSpace = GeneralMemoryAllocator::get().allocLowSpeed(sizeof(NumericLayerBasicText));
if (!layerSpace) {
return;
}
Expand Down Expand Up @@ -147,7 +148,8 @@ void SevenSegment::setText(std::string_view newText, bool alignRight, uint8_t dr

NumericLayerScrollingText* SevenSegment::setScrollingText(char const* newText, int32_t startAtTextPos,
int32_t initialDelay) {
void* layerSpace = GeneralMemoryAllocator::get().alloc(sizeof(NumericLayerScrollingText));
// Paul: Render time could be lower putting this into internal
void* layerSpace = GeneralMemoryAllocator::get().allocLowSpeed(sizeof(NumericLayerScrollingText));
if (!layerSpace) {
return NULL;
}
Expand Down Expand Up @@ -195,7 +197,8 @@ void SevenSegment::transitionToNewLayer(NumericLayer* newLayer) {
// If transition...
if (!popupActive && nextTransitionDirection != 0 && topLayer != NULL) {

void* layerSpace = GeneralMemoryAllocator::get().alloc(sizeof(NumericLayerScrollTransition));
// Paul: Render time could be lower putting this into internal
void* layerSpace = GeneralMemoryAllocator::get().allocLowSpeed(sizeof(NumericLayerScrollTransition));

if (layerSpace) {
scrollTransition = new (layerSpace) NumericLayerScrollTransition();
Expand Down Expand Up @@ -541,7 +544,8 @@ void SevenSegment::render() {

// Call this to make the loading animation happen
void SevenSegment::displayLoadingAnimation(bool delayed, bool transparent) {
void* layerSpace = GeneralMemoryAllocator::get().alloc(sizeof(NumericLayerLoadingAnimation));
// Paul: Render time could be lower putting this into internal
void* layerSpace = GeneralMemoryAllocator::get().allocLowSpeed(sizeof(NumericLayerLoadingAnimation));
if (!layerSpace) {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/deluge/hid/hid_sysex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ void HIDSysex::requestOLEDDisplay(MIDIDevice* device, uint8_t* data, int32_t len
}

if (oledDeltaImage == nullptr) {
oledDeltaImage = (uint8_t*)GeneralMemoryAllocator::get().alloc(
sizeof(uint8_t[OLED_MAIN_HEIGHT_PIXELS >> 3][OLED_MAIN_WIDTH_PIXELS]), NULL, false, true);
oledDeltaImage = (uint8_t*)GeneralMemoryAllocator::get().allocMaxSpeed(
sizeof(uint8_t[OLED_MAIN_HEIGHT_PIXELS >> 3][OLED_MAIN_WIDTH_PIXELS]));
}
}
sendDisplayIfChanged();
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/io/debug/sysex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ static void firstPacket(uint8_t* data, int32_t len) {
}
load_bufsize = load_codesize + (511 - ((load_codesize - 1) & 511));

load_buf = (uint8_t*)GeneralMemoryAllocator::get().alloc(load_bufsize, NULL, false, true);
load_buf = (uint8_t*)GeneralMemoryAllocator::get().allocMaxSpeed(load_bufsize);
if (load_buf == nullptr) {
// fail :(
return;
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/io/midi/midi_device_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ MIDIDeviceUSBHosted* getOrCreateHostedMIDIDeviceFromDetails(String* name, uint16
return NULL;
}

void* memory = GeneralMemoryAllocator::get().alloc(sizeof(MIDIDeviceUSBHosted), NULL, false, true);
void* memory = GeneralMemoryAllocator::get().allocMaxSpeed(sizeof(MIDIDeviceUSBHosted));
if (!memory) {
return NULL;
}
Expand Down
4 changes: 2 additions & 2 deletions src/deluge/memory/fallback_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ class fallback_allocator {
if (n == 0) {
return nullptr;
}
return static_cast<T*>(GeneralMemoryAllocator::get().allocNonAudio(n * sizeof(T)));
return static_cast<T*>(GeneralMemoryAllocator::get().allocExternal(n * sizeof(T)));
}

void deallocate(T* p, std::size_t n) { delugeDeallocNonAudio(p); }
void deallocate(T* p, std::size_t n) { delugeDeallocExternal(p); }

template <typename U>
bool operator==(const deluge::memory::fallback_allocator<U>& o) {
Expand Down
Loading