From 1a4fe6f79e7d178855408e306e4867277e3efecc Mon Sep 17 00:00:00 2001
From: fennecdjay <fennecdjay@gmail.com>
Date: Tue, 12 Jul 2022 21:25:09 +0200
Subject: [PATCH] :art: Improve shreduler

---
 src/compile.c      |  2 ++
 src/lib/shred.c    |  1 -
 src/vm/shreduler.c | 41 +++++++++++++++++++++--------------------
 3 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/src/compile.c b/src/compile.c
index 2974fdef..c9b3ad9e 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -7,6 +7,7 @@
 #include "compile.h"
 #include "gwion.h"
 #include "pass.h"
+#include "shreduler_private.h"
 
 enum compile_type { COMPILE_NAME, COMPILE_MSTR, COMPILE_FILE };
 
@@ -178,6 +179,7 @@ ANN m_uint compile_string_xid(struct Gwion_ *gwion, const m_str filename,
   struct Compiler c = {.base = filename, .type = COMPILE_MSTR, .data = data};
   if (!compile(gwion, &c)) return 0;
   assert(c.shred);
+  gwion->vm->shreduler->shred_ids--;
   return c.shred->tick->xid = xid;
 }
 
diff --git a/src/lib/shred.c b/src/lib/shred.c
index 7d585680..e7d51842 100644
--- a/src/lib/shred.c
+++ b/src/lib/shred.c
@@ -50,7 +50,6 @@ ANN M_Object new_fork(const VM_Shred shred, const VM_Code code, const Type t) {
   vm->parent            = parent;
   const M_Object o = sh->info->me = fork_object(shred, t);
   ME(o)                           = sh;
-//  ++o->ref;
   shreduler_add(vm->shreduler, sh);
   return o;
 }
diff --git a/src/vm/shreduler.c b/src/vm/shreduler.c
index a849dd79..7e558b78 100644
--- a/src/vm/shreduler.c
+++ b/src/vm/shreduler.c
@@ -17,7 +17,7 @@ ANN VM_Shred shreduler_get(const Shreduler s) {
   Driver *const            bbq = s->bbq;
   struct ShredTick_ *const tk  = s->list;
   if (tk) {
-    const m_float time = (m_float)bbq->pos + (m_float)GWION_EPSILON;
+    const m_float time = (m_float)bbq->pos + GWION_EPSILON;
     if (tk->wake_time <= time) {
       if ((s->list = tk->next)) s->list->prev = NULL;
       tk->next = tk->prev = NULL;
@@ -31,45 +31,46 @@ ANN VM_Shred shreduler_get(const Shreduler s) {
   return NULL;
 }
 
-ANN static inline void shreduler_child(const Vector v) {
+ANN static void shreduler_erase(const Shreduler, struct ShredTick_ *const);
+
+ANN static void tk_remove(const Shreduler s, struct ShredTick_ *const tk) {
+  if (tk == s->curr) s->curr = NULL;
+  else if (tk == s->list) s->list = tk->next;
+  if (tk->prev) tk->prev->next = tk->next;
+  if (tk->next) tk->next->prev = tk->prev;
+}
+
+ANN static inline void child(const Shreduler s, const Vector v) {
   for (m_uint i = vector_size(v) + 1; --i;) {
     const VM_Shred child = (VM_Shred)vector_at(v, i - 1);
-    shreduler_remove(child->tick->shreduler, child, true);
+    struct ShredTick_ *const tk = child->tick;
+    tk_remove(s, tk);
+    shreduler_erase(s, tk);
   }
 }
 
 ANN static void shreduler_erase(const Shreduler          s,
                                 struct ShredTick_ *const tk) {
   const VM_Shred shred = tk->self;
+  if (tk->child.ptr) child(s, &tk->child);
+  MUTEX_LOCK(shred->mutex);
+  tk->prev = (struct ShredTick_*)-1;
+  MUTEX_UNLOCK(shred->mutex);
   const m_uint size =
       shred->info->frame.ptr ? vector_size(&shred->info->frame) : 0;
   unwind(shred, (Symbol)-1, size);
-  MUTEX_LOCK(shred->mutex);
-  if (tk->parent) {
-    MUTEX_LOCK(tk->parent->self->mutex);
-    vector_rem2(&tk->parent->child, (vtype)tk->self);
-    MUTEX_UNLOCK(tk->parent->self->mutex);
-  }
-  if (tk->child.ptr) shreduler_child(&tk->child);
   vector_rem2(&s->active_shreds, (vtype)shred);
-  MUTEX_UNLOCK(shred->mutex);
 }
 
 ANN void shreduler_remove(const Shreduler s, const VM_Shred out,
                           const bool erase) {
   MUTEX_LOCK(s->mutex);
   struct ShredTick_ *const tk = out->tick;
-  if (tk == s->curr)
-    s->curr = NULL;
-  else if (tk == s->list)
-    s->list = tk->next;
-  if (tk->prev) tk->prev->next = tk->next;
-  if (tk->next) tk->next->prev = tk->prev;
-  if (!erase)
-    tk->prev = tk->next = NULL;
+  tk_remove(s, tk);
+  if (likely(!erase)) tk->prev = tk->next = NULL;
   else {
     shreduler_erase(s, tk);
-    tk->prev = (struct ShredTick_*)-1;
+    if (tk->parent) vector_rem2(&tk->parent->child, (vtype)out);
     release(out->info->me, out);
   }
   MUTEX_UNLOCK(s->mutex);
-- 
2.43.0