Gwion coverage report


Directory: src/
File: src/vm/shreduler.c
Date: 2023-01-30 18:32:28
Exec Total Coverage
Lines: 98 98 100.0%
Functions: 12 12 100.0%
Branches: 42 44 95.5%

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