Jelajahi Sumber

【完善】GC 适配代码。

Signed-off-by: armink <armink.ztl@gmail.com>
armink 7 tahun lalu
induk
melakukan
8212c07052
3 mengubah file dengan 18 tambahan dan 40 penghapusan
  1. 4 24
      port/gccollect.c
  2. 11 13
      port/mpthreadport.c
  3. 3 3
      port/mpy_main.c

+ 4 - 24
port/gccollect.c

@@ -28,35 +28,15 @@
 #include "py/mpstate.h"
 #include "py/gc.h"
 
-// If we don't have architecture-specific optimized support,
-// just fall back to setjmp-based implementation.
-
-// If MICROPY_GCREGS_SETJMP was requested explicitly, or if
-// we enabled it as a fallback above.
-#include <setjmp.h>
-
-typedef jmp_buf regs_t;
-
-STATIC void gc_helper_get_regs(regs_t arr) {
-    setjmp(arr);
-}
-
-void gc_collect_regs_and_stack(void) {
-    regs_t regs;
-    gc_helper_get_regs(regs);
-    // GC stack (and regs because we captured them)
-    void **regs_ptr = (void**)(void*)&regs;
-    gc_collect_root(regs_ptr, ((uintptr_t)MP_STATE_THREAD(stack_top) - (uintptr_t)&regs) / sizeof(uintptr_t));
-}
-
 void gc_collect(void) {
     gc_collect_start();
-    // trace root pointers from any threads
-    gc_collect_regs_and_stack();
 
 #if MICROPY_PY_THREAD
-    //TODO has some problem when multithreading using gc at the same time
+    // trace root pointers from any threads
     mp_thread_gc_others();
+#else
+    // gc the main thread stack
+    gc_collect_root(rt_thread_self()->stack_addr, ((mp_uint_t)((void *)MP_STATE_THREAD(stack_top) - rt_thread_self()->stack_addr)) / 4);
 #endif
 
     gc_collect_end();

+ 11 - 13
port/mpthreadport.c

@@ -61,8 +61,8 @@ STATIC thread_t *thread_root; // root pointer, handled by mp_thread_gc_others
 /**
  * thread port initialization
  *
- * @param stack MicroPython main thread stack
- * @param stack_len MicroPython main thread stack
+ * @param stack MicroPython main thread stack start address
+ * @param stack_len number of words in the stack
  */
 void mp_thread_init(void *stack, uint32_t stack_len) {
     mp_thread_set_state(&mp_state_ctx.thread);
@@ -82,20 +82,18 @@ void mp_thread_gc_others(void) {
 
     mp_thread_mutex_lock(&thread_mutex, 1);
     for (thread_t *th = thread_root; th != NULL; th = th->next) {
-        if (th == &thread_root_node) {
-            continue;
+        // the root node not using the mpy heap
+        if (th != &thread_root_node) {
+            gc_collect_root((void**)&th, 1);
+            gc_collect_root(&th->arg, 1); // probably not needed
         }
-        gc_collect_root((void**)&th, 1);
-        gc_collect_root(&th->arg, 1); // probably not needed
 
-        if (th->id == rt_thread_self()) {
+        if (th->status == MP_THREAD_STATUS_READY) {
             continue;
         }
-        if (th->status != MP_THREAD_STATUS_FINISH) {
-            continue;
-        }
-        gc_collect_root((void**)&th->id, 1); // probably not needed
-        gc_collect_root((void**)&th->stack, th->stack_len); // probably not needed
+
+        gc_collect_root((void**) &th->id, 1); // probably not needed
+        gc_collect_root(th->stack, th->stack_len); // probably not needed
     }
     mp_thread_mutex_unlock(&thread_mutex);
 }
@@ -150,7 +148,7 @@ void mp_thread_create_ex(void *(*entry)(void*), void *arg, size_t *stack_size, i
     // add thread to linked list of all threads
     th->status = MP_THREAD_STATUS_READY;
     th->arg = arg;
-    th->stack_len = *stack_size;
+    th->stack_len = *stack_size / 4;
     th->next = thread_root;
     thread_root = th;
 

+ 3 - 3
port/mpy_main.c

@@ -63,17 +63,17 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) {
 }
 #endif
 
-static char *stack_top = RT_NULL;
+static void *stack_top = RT_NULL;
 static char *heap = RT_NULL;
 
 void mpy_main(const char *filename) {
     int stack_dummy;
-    stack_top = (char*)&stack_dummy;
+    stack_top = (void *)&stack_dummy;
 
     rtt_getchar_init();
 
 #if MICROPY_PY_THREAD
-    mp_thread_init(rt_thread_self()->stack_addr, rt_thread_self()->stack_size / 4);
+    mp_thread_init(rt_thread_self()->stack_addr, (rt_uint32_t)(stack_top - rt_thread_self()->stack_addr) / 4);
 #endif
 
     mp_stack_set_top(stack_top);