| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include <stdlib.h> | ||
| 2 | #include "gwion_util.h" | ||
| 3 | #include "gwion_ast.h" | ||
| 4 | #include "gwion_env.h" | ||
| 5 | #include "vm.h" | ||
| 6 | #include "gwion.h" | ||
| 7 | #include "object.h" | ||
| 8 | #include "driver.h" | ||
| 9 | #include "shreduler_private.h" | ||
| 10 | |||
| 11 | 707 | ANN void shreduler_set_loop(const Shreduler s, const bool loop) { | |
| 12 | 707 | s->loop = loop; | |
| 13 | 707 | } | |
| 14 | |||
| 15 | 6064604 | ANN VM_Shred shreduler_get(const Shreduler s) { | |
| 16 | 6064604 | MUTEX_LOCK(s->mutex); | |
| 17 | 6159456 | Driver *const bbq = s->bbq; | |
| 18 | 6159456 | struct ShredTick_ *const tk = s->list; | |
| 19 |
2/2✓ Branch 0 taken 3840616 times.
✓ Branch 1 taken 2318840 times.
|
6159456 | if (tk) { |
| 20 | 3840616 | const m_float time = (m_float)bbq->pos + GWION_EPSILON; | |
| 21 |
2/2✓ Branch 0 taken 573 times.
✓ Branch 1 taken 3840043 times.
|
3840616 | if (tk->wake_time <= time) { |
| 22 |
2/2✓ Branch 0 taken 164 times.
✓ Branch 1 taken 409 times.
|
573 | if ((s->list = tk->next)) s->list->prev = NULL; |
| 23 | 573 | tk->next = tk->prev = NULL; | |
| 24 | 573 | s->curr = tk; | |
| 25 | 573 | MUTEX_UNLOCK(s->mutex); | |
| 26 | 573 | return tk->self; | |
| 27 | } | ||
| 28 | } | ||
| 29 |
4/4✓ Branch 0 taken 5591874 times.
✓ Branch 1 taken 567009 times.
✓ Branch 3 taken 642 times.
✓ Branch 4 taken 5600014 times.
|
6158883 | if (!s->loop && !vector_size(&s->active_shreds)) bbq->is_running = 0; |
| 30 | 6167665 | MUTEX_UNLOCK(s->mutex); | |
| 31 | 6147975 | return NULL; | |
| 32 | } | ||
| 33 | |||
| 34 | ANN static void shreduler_erase(const Shreduler, struct ShredTick_ *const); | ||
| 35 | |||
| 36 | 461 | ANN static void tk_remove(const Shreduler s, struct ShredTick_ *const tk) { | |
| 37 |
2/2✓ Branch 0 taken 410 times.
✓ Branch 1 taken 51 times.
|
461 | if (tk == s->curr) s->curr = NULL; |
| 38 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 41 times.
|
51 | else if (tk == s->list) s->list = tk->next; |
| 39 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 449 times.
|
461 | if (tk->prev) tk->prev->next = tk->next; |
| 40 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 456 times.
|
461 | if (tk->next) tk->next->prev = tk->prev; |
| 41 | 461 | } | |
| 42 | |||
| 43 | 31 | ANN static inline void child(const Shreduler s, const Vector v) { | |
| 44 |
2/2✓ Branch 1 taken 24 times.
✓ Branch 2 taken 31 times.
|
55 | for (m_uint i = vector_size(v) + 1; --i;) { |
| 45 | 24 | const VM_Shred shred = (VM_Shred)vector_at(v, i - 1); | |
| 46 | 24 | struct ShredTick_ *const tk = shred->tick; | |
| 47 | 24 | tk_remove(s, tk); | |
| 48 | 24 | shreduler_erase(s, tk); | |
| 49 | } | ||
| 50 | 31 | } | |
| 51 | |||
| 52 | 425 | ANN static void shreduler_erase(const Shreduler s, | |
| 53 | struct ShredTick_ *const tk) { | ||
| 54 | 425 | const VM_Shred shred = tk->self; | |
| 55 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 394 times.
|
425 | if (tk->child.ptr) child(s, &tk->child); |
| 56 | 425 | MUTEX_LOCK(shred->mutex); | |
| 57 | 425 | tk->prev = (struct ShredTick_*)-1; | |
| 58 | 425 | MUTEX_UNLOCK(shred->mutex); | |
| 59 | 425 | const m_uint size = | |
| 60 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 422 times.
|
425 | shred->info->frame.ptr ? vector_size(&shred->info->frame) : 0; |
| 61 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 425 times.
|
425 | if(size) unwind(shred, (Symbol)-1, size); |
| 62 | 425 | vector_rem2(&s->active_shreds, (vtype)shred); | |
| 63 | 425 | release(shred->info->me, shred); | |
| 64 | 425 | } | |
| 65 | |||
| 66 | 437 | ANN void shreduler_remove(const Shreduler s, const VM_Shred out, | |
| 67 | const bool erase) { | ||
| 68 | 437 | MUTEX_LOCK(s->mutex); | |
| 69 | 437 | struct ShredTick_ *const tk = out->tick; | |
| 70 | 437 | tk_remove(s, tk); | |
| 71 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 401 times.
|
437 | if (likely(!erase)) tk->prev = tk->next = NULL; |
| 72 | else { | ||
| 73 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 351 times.
|
401 | if (tk->parent) vector_rem2(&tk->parent->child, (vtype)out); |
| 74 | 401 | shreduler_erase(s, tk); | |
| 75 | } | ||
| 76 | 437 | MUTEX_UNLOCK(s->mutex); | |
| 77 | 437 | } | |
| 78 | |||
| 79 | 599 | ANN static void _shredule(const Shreduler s, struct ShredTick_ *tk, | |
| 80 | const m_float wake_time) { | ||
| 81 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 599 times.
|
599 | if(tk->prev == (struct ShredTick_*)-1) return; |
| 82 | 599 | const m_float time = wake_time + (m_float)s->bbq->pos; | |
| 83 | 599 | tk->wake_time = time; | |
| 84 |
2/2✓ Branch 0 taken 179 times.
✓ Branch 1 taken 420 times.
|
599 | if (s->list) { |
| 85 | 179 | struct ShredTick_ *curr = s->list, *prev = NULL; | |
| 86 | do { | ||
| 87 |
2/2✓ Branch 0 taken 74 times.
✓ Branch 1 taken 533 times.
|
607 | if (curr->wake_time > time) break; |
| 88 | 533 | prev = curr; | |
| 89 |
2/2✓ Branch 0 taken 428 times.
✓ Branch 1 taken 105 times.
|
533 | } while ((curr = curr->next)); |
| 90 |
2/2✓ Branch 0 taken 68 times.
✓ Branch 1 taken 111 times.
|
179 | if (!prev) { |
| 91 | 68 | tk->next = s->list; | |
| 92 | 68 | s->list = s->list->prev = tk; | |
| 93 | } else { | ||
| 94 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 105 times.
|
111 | if ((tk->next = prev->next)) prev->next->prev = tk; |
| 95 | 111 | tk->prev = prev; | |
| 96 | 111 | prev->next = tk; | |
| 97 | } | ||
| 98 | 420 | } else s->list = tk; | |
| 99 |
2/2✓ Branch 0 taken 163 times.
✓ Branch 1 taken 436 times.
|
599 | if (tk == s->curr) s->curr = NULL; |
| 100 | } | ||
| 101 | |||
| 102 | 170 | ANN void shredule(const Shreduler s, const VM_Shred shred, | |
| 103 | const m_float wake_time) { | ||
| 104 | 170 | struct ShredTick_ *tk = shred->tick; | |
| 105 | 170 | MUTEX_LOCK(s->mutex); | |
| 106 | 170 | _shredule(s, tk, wake_time); | |
| 107 | 170 | MUTEX_UNLOCK(s->mutex); | |
| 108 | 170 | } | |
| 109 | |||
| 110 | 1067 | ANN void shreduler_ini(const Shreduler s, const VM_Shred shred) { | |
| 111 | 1067 | shred->tick = mp_calloc(shred->info->mp, ShredTick); | |
| 112 | 1067 | shred->tick->self = shred; | |
| 113 | 1067 | shred->tick->shreduler = s; | |
| 114 | 1067 | } | |
| 115 | |||
| 116 | 429 | ANN void shreduler_add(const Shreduler s, const VM_Shred shred) { | |
| 117 | 429 | shreduler_ini(s, shred); | |
| 118 | 429 | shred->tick->xid = ++s->shred_ids; | |
| 119 | 429 | MUTEX_LOCK(s->mutex); | |
| 120 | 429 | vector_add(&s->active_shreds, (vtype)shred); | |
| 121 | 429 | _shredule(s, shred->tick, GWION_EPSILON); | |
| 122 | 429 | MUTEX_UNLOCK(s->mutex); | |
| 123 | 429 | } | |
| 124 | |||
| 125 | 712 | ANN Shreduler new_shreduler(const MemPool mp) { | |
| 126 | 712 | Shreduler s = (Shreduler)mp_calloc(mp, Shreduler); | |
| 127 | 712 | vector_init(&s->active_shreds); | |
| 128 | 712 | MUTEX_SETUP(s->mutex); | |
| 129 | 712 | return s; | |
| 130 | } | ||
| 131 | |||
| 132 | 708 | ANN void free_shreduler(const MemPool mp, const Shreduler s) { | |
| 133 | 708 | vector_release(&s->active_shreds); | |
| 134 | 708 | MUTEX_CLEANUP(s->mutex); | |
| 135 | 708 | mp_free(mp, Shreduler, s); | |
| 136 | 708 | } | |
| 137 |