@@ -126,35 +126,47 @@ uint8_t value_out = 0;
126
126
#include "shared-module/os/__init__.h"
127
127
#endif
128
128
129
+ typedef struct {
130
+ #if MICROPY_ENABLE_PYSTACK
131
+ supervisor_allocation * pystack ;
132
+ #endif
133
+ supervisor_allocation * heap ;
134
+ } stacks ;
135
+
129
136
static void reset_devices (void ) {
130
137
#if CIRCUITPY_BLEIO_HCI
131
138
bleio_reset ();
132
139
#endif
133
140
}
134
141
135
142
#if MICROPY_ENABLE_PYSTACK
136
- STATIC supervisor_allocation __attribute__ ((noinline )) * alloc_pystack (void ) {
143
+ STATIC stacks __attribute__ ((noinline )) alloc_stacks (void ) {
144
+ stacks res ;
145
+ #if MICROPY_ENABLE_PYSTACK
137
146
mp_int_t pystack_size = CIRCUITPY_PYSTACK_SIZE ;
138
147
#if CIRCUITPY_OS_GETENV
139
148
// Fetch value if exists from settings.toml
140
149
// Leaves size to build default on any failure
141
150
(void )common_hal_os_getenv_int ("CIRCUITPY_PYSTACK_SIZE" , & pystack_size );
142
151
// Check if value is valid
143
- if ((CIRCUITPY_PYSTACK_SIZE != pystack_size ) && ((pystack_size < 384 ) || (pystack_size % sizeof (size_t ) != 0 ))) {
152
+ pystack_size = pystack_size - pystack_size % sizeof (size_t ); // Round down to multiple of 4.
153
+ if ((CIRCUITPY_PYSTACK_SIZE != pystack_size ) && (pystack_size < 384 )) {
144
154
serial_write_compressed (translate ("\nWARNING: Invalid CIRCUITPY_PYSTACK_SIZE, defaulting back to build value.\n\n" ));
145
155
pystack_size = CIRCUITPY_PYSTACK_SIZE ; // Reset
146
156
}
147
157
#endif
148
- supervisor_allocation * pystack = allocate_memory (pystack_size , false, false);
149
- if (pystack == NULL ) {
158
+ res . pystack = allocate_memory (pystack_size , false, false);
159
+ if (res . pystack == NULL ) {
150
160
serial_write_compressed (translate ("\nWARNING: Allocating pystack failed, defaulting back to build value. \n\n" ));
151
- pystack = allocate_memory (CIRCUITPY_PYSTACK_SIZE , false, false);
161
+ res . pystack = allocate_memory (CIRCUITPY_PYSTACK_SIZE , false, false);
152
162
}
153
- return pystack ;
163
+ #endif
164
+ res .heap = allocate_remaining_memory ();
165
+ return res ;
154
166
}
155
167
#endif
156
168
157
- STATIC void start_mp (supervisor_allocation * heap , supervisor_allocation * pystack ) {
169
+ STATIC void start_mp (stacks combo ) {
158
170
supervisor_workflow_reset ();
159
171
160
172
// Stack limit should be less than real stack size, so we have a chance
@@ -182,11 +194,11 @@ STATIC void start_mp(supervisor_allocation *heap, supervisor_allocation *pystack
182
194
readline_init0 ();
183
195
184
196
#if MICROPY_ENABLE_PYSTACK
185
- mp_pystack_init (pystack -> ptr , pystack -> ptr + ( get_allocation_length (pystack ) / sizeof (size_t ) ));
197
+ mp_pystack_init (combo . pystack -> ptr , combo . pystack -> ptr + get_allocation_length (combo . pystack ) / sizeof (size_t ));
186
198
#endif
187
199
188
200
#if MICROPY_ENABLE_GC
189
- gc_init (heap -> ptr , heap -> ptr + get_allocation_length (heap ) / 4 );
201
+ gc_init (combo . heap -> ptr , combo . heap -> ptr + get_allocation_length (combo . heap ) / 4 );
190
202
#endif
191
203
mp_init ();
192
204
mp_obj_list_init ((mp_obj_list_t * )mp_sys_path , 0 );
@@ -286,7 +298,7 @@ STATIC void count_strn(void *data, const char *str, size_t len) {
286
298
* (size_t * )data += len ;
287
299
}
288
300
289
- STATIC void cleanup_after_vm (supervisor_allocation * heap , supervisor_allocation * pystack , mp_obj_t exception ) {
301
+ STATIC void cleanup_after_vm (stacks combo , mp_obj_t exception ) {
290
302
// Get the traceback of any exception from this run off the heap.
291
303
// MP_OBJ_SENTINEL means "this run does not contribute to traceback storage, don't touch it"
292
304
// MP_OBJ_NULL (=0) means "this run completed successfully, clear any stored traceback"
@@ -366,8 +378,8 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, supervisor_allocation
366
378
// Free the heap last because other modules may reference heap memory and need to shut down.
367
379
filesystem_flush ();
368
380
stop_mp ();
369
- free_memory (heap );
370
- free_memory (pystack );
381
+ free_memory (combo . heap );
382
+ free_memory (combo . pystack );
371
383
supervisor_move_memory ();
372
384
373
385
// Let the workflows know we've reset in case they want to restart.
@@ -422,11 +434,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) {
422
434
};
423
435
#endif
424
436
425
- #if MICROPY_ENABLE_PYSTACK
426
- supervisor_allocation * pystack = alloc_pystack ();
427
- #endif
428
- supervisor_allocation * heap = allocate_remaining_memory ();
429
- start_mp (heap , pystack );
437
+ stacks combo = alloc_stacks ();
438
+ start_mp (combo );
430
439
431
440
#if CIRCUITPY_USB
432
441
usb_setup_with_vm ();
@@ -474,7 +483,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) {
474
483
475
484
476
485
// Finished executing python code. Cleanup includes filesystem flush and a board reset.
477
- cleanup_after_vm (heap , pystack , _exec_result .exception );
486
+ cleanup_after_vm (combo , _exec_result .exception );
478
487
_exec_result .exception = NULL ;
479
488
480
489
// If a new next code file was set, that is a reason to keep it (obviously). Stuff this into
@@ -770,11 +779,8 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
770
779
771
780
// Do USB setup even if boot.py is not run.
772
781
773
- #if MICROPY_ENABLE_PYSTACK
774
- supervisor_allocation * pystack = alloc_pystack ();
775
- #endif
776
- supervisor_allocation * heap = allocate_remaining_memory ();
777
- start_mp (heap , pystack );
782
+ stacks combo = alloc_stacks ();
783
+ start_mp (combo );
778
784
779
785
#if CIRCUITPY_USB
780
786
// Set up default USB values after boot.py VM starts but before running boot.py.
@@ -860,7 +866,7 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
860
866
861
867
port_post_boot_py (true);
862
868
863
- cleanup_after_vm (heap , pystack , _exec_result .exception );
869
+ cleanup_after_vm (combo , _exec_result .exception );
864
870
_exec_result .exception = NULL ;
865
871
866
872
port_post_boot_py (false);
@@ -875,11 +881,8 @@ STATIC int run_repl(void) {
875
881
int exit_code = PYEXEC_FORCED_EXIT ;
876
882
stack_resize ();
877
883
filesystem_flush ();
878
- #if MICROPY_ENABLE_PYSTACK
879
- supervisor_allocation * pystack = alloc_pystack ();
880
- #endif
881
- supervisor_allocation * heap = allocate_remaining_memory ();
882
- start_mp (heap , pystack );
884
+ stacks combo = alloc_stacks ();
885
+ start_mp (combo );
883
886
884
887
#if CIRCUITPY_USB
885
888
usb_setup_with_vm ();
@@ -922,7 +925,7 @@ STATIC int run_repl(void) {
922
925
exit_code = PYEXEC_DEEP_SLEEP ;
923
926
}
924
927
#endif
925
- cleanup_after_vm (heap , pystack , MP_OBJ_SENTINEL );
928
+ cleanup_after_vm (combo , MP_OBJ_SENTINEL );
926
929
927
930
// Also reset bleio. The above call omits it in case workflows should continue. In this case,
928
931
// we're switching straight to another VM so we want to reset.
0 commit comments