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 |