Skip to content

Commit 63c3c01

Browse files
committed
terminal: Correct logic error in supervisor_start_terminal
If `supervisor_start_terminal` is called twice in a row without `supervisor_stop_terminal`, it would lose track of a supervisor allocation. This can occur when setting the rotation of a display, including the way that a FramebufferDisplay sets rotation _AFTER_ initial construction, first with a stack like ``` #0 supervisor_start_terminal #1 in displayio_display_core_construct #2 in common_hal_framebufferio_framebufferdisplay_construct ``` and then with a stack like ``` #0 supervisor_start_terminal #1 in common_hal_framebufferio_framebufferdisplay_construct #2 in framebufferio_framebufferdisplay_make_new ``` .. without an intervening stop_terminal call. For reasons I didn't fully explore, this did not become a problem until the ability to re-allocate a freed supervisor allocation was implemented in adafruit#3482. Demonstrating the problem requires adafruit#3482 + adafruit#3497 + this PR.
1 parent 8d55bf9 commit 63c3c01

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

supervisor/shared/display.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,20 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) {
7878

7979
uint16_t total_tiles = width_in_tiles * height_in_tiles;
8080

81-
// First try to allocate outside the heap. This will fail when the VM is running.
82-
tilegrid_tiles = allocate_memory(align32_size(total_tiles), false);
81+
// Reuse the previous allocation if possible
82+
if (tilegrid_tiles) {
83+
if (tilegrid_tiles->length != align32_size(total_tiles)) {
84+
free_memory(tilegrid_tiles);
85+
tilegrid_tiles = NULL;
86+
}
87+
}
88+
// Next try to allocate outside the heap. This will fail when the VM is running.
89+
if (!tilegrid_tiles) {
90+
tilegrid_tiles = allocate_memory(align32_size(total_tiles), false);
91+
}
92+
93+
// Finally, allocate inside the heap. This will be promoted to a GC
94+
// allocation at soft reset by supervisor_display_move_memory.
8395
uint8_t* tiles;
8496
if (tilegrid_tiles == NULL) {
8597
tiles = m_malloc(total_tiles, true);

0 commit comments

Comments
 (0)