GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/vm/shreduler.c Lines: 85 85 100.0 %
Date: 2020-08-07 19:15:19 Branches: 40 40 100.0 %

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 "object.h"
7
#include "driver.h"
8
#include "shreduler_private.h"
9
10
730
ANN void shreduler_set_loop(const Shreduler s, const m_bool loop) {
11
730
  s->loop = loop > 0;
12
730
}
13
14
6031491
ANN VM_Shred shreduler_get(const Shreduler s) {
15
6031491
  Driver *const bbq = s->bbq;
16
6031491
  struct ShredTick_ *const tk = s->list;
17
6031491
  if(!tk) {
18

2142544
    if(!vector_size(&s->shreds) && !s->loop)
19
733
      bbq->is_running = 0;
20
2142544
    return NULL;
21
  }
22
3888947
  const m_float time = (m_float)bbq->pos + (m_float)GWION_EPSILON;
23
3888947
  if(tk->wake_time <= time) {
24
626
    if((s->list = tk->next))
25
160
      s->list->prev = NULL;
26
626
    tk->next = tk->prev = NULL;
27
626
    s->curr = tk;
28
626
    return tk->self;
29
  }
30
3888321
  return NULL;
31
}
32
33
75
ANN static void shreduler_parent(const VM_Shred out, const Vector v) {
34
75
  vector_rem2(v, (vtype)out);
35
75
  if(!vector_size(v)) {
36
32
    vector_release(v);
37
32
    out->tick->parent->child.ptr = NULL;
38
  }
39
75
}
40
41
10
ANN static inline void shreduler_child(const Vector v) {
42
43
  for(m_uint i = vector_size(v) + 1; --i;) {
43
23
    const VM_Shred child = (VM_Shred)vector_at(v, i - 1);
44
23
    shreduler_remove(child->info->vm->shreduler, child, 1);
45
  }
46
10
}
47
48
483
ANN static void shreduler_erase(const Shreduler s, struct ShredTick_ *tk) {
49
483
  if(tk->parent)
50
75
    shreduler_parent(tk->self, &tk->parent->child);
51
483
  if(tk->child.ptr)
52
10
    shreduler_child(&tk->child);
53
483
  vector_rem2(&s->shreds, (vtype)tk->self);
54
483
}
55
56
493
ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase) {
57
493
  MUTEX_LOCK(s->mutex);
58
493
  struct ShredTick_ *tk = out->tick;
59
493
  if(tk == s->curr)
60
470
    s->curr = NULL;
61
23
  else if(tk == s->list)
62
7
    s->list = tk->next;
63
493
  if(tk->prev)
64
15
    tk->prev->next = tk->next;
65
493
  if(tk->next)
66
5
    tk->next->prev = tk->prev;
67
493
  tk->prev = tk->next = NULL;
68
493
  if(erase) {
69
483
    shreduler_erase(s, tk);
70
483
    _release(out->info->me, out);
71
  }
72
493
  MUTEX_UNLOCK(s->mutex);
73
493
}
74
75
651
ANN void shredule(const Shreduler s, const VM_Shred shred, const m_float wake_time) {
76
651
  const m_float time = wake_time + (m_float)s->bbq->pos;
77
651
  struct ShredTick_ *tk = shred->tick;
78
651
  tk->wake_time = time;
79
651
  if(s->list) {
80
178
    struct ShredTick_ *curr = s->list, *prev = NULL;
81
    do {
82
624
      if(curr->wake_time > time)
83
72
        break;
84
552
      prev = curr;
85
552
    } while((curr = curr->next));
86
178
    if(!prev) {
87
66
      tk->next = s->list;
88
66
      s->list = (s->list->prev = tk);
89
    } else {
90
112
      if((tk->next = prev->next))
91
6
        prev->next->prev = tk;
92
112
      tk->prev = prev;
93
112
      prev->next = tk;
94
    }
95
  } else
96
473
    s->list = tk;
97
651
  if(tk == s->curr)
98
156
    s->curr = NULL;
99
651
}
100
101
1219
ANN void shreduler_ini(const Shreduler s, const VM_Shred shred) {
102
1219
  shred->tick = mp_calloc(shred->info->mp, ShredTick);
103
1219
  shred->tick->self = shred;
104
1219
  shred->tick->shreduler = s;
105
1219
}
106
107
486
ANN void shreduler_add(const Shreduler s, const VM_Shred shred) {
108
486
  shreduler_ini(s, shred);
109
486
  shred->tick->xid = ++s->shred_ids;
110
486
  vector_add(&s->shreds, (vtype)shred);
111
486
  shredule(s, shred, GWION_EPSILON);
112
486
}