GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/vm/shreduler.c Lines: 85 85 100.0 %
Date: 2020-09-12 17:36:58 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
711
ANN void shreduler_set_loop(const Shreduler s, const m_bool loop) {
11
711
  s->loop = loop > 0;
12
711
}
13
14
5640688
ANN VM_Shred shreduler_get(const Shreduler s) {
15
5640688
  Driver *const bbq = s->bbq;
16
5640688
  struct ShredTick_ *const tk = s->list;
17
5640688
  if(!tk) {
18

1751997
    if(!vector_size(&s->shreds) && !s->loop)
19
714
      bbq->is_running = 0;
20
1751997
    return NULL;
21
  }
22
3888691
  const m_float time = (m_float)bbq->pos + (m_float)GWION_EPSILON;
23
3888691
  if(tk->wake_time <= time) {
24
636
    if((s->list = tk->next))
25
160
      s->list->prev = NULL;
26
636
    tk->next = tk->prev = NULL;
27
636
    s->curr = tk;
28
636
    return tk->self;
29
  }
30
3888055
  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
494
ANN static void shreduler_erase(const Shreduler s, struct ShredTick_ *tk) {
49
494
  if(tk->parent)
50
75
    shreduler_parent(tk->self, &tk->parent->child);
51
494
  if(tk->child.ptr)
52
10
    shreduler_child(&tk->child);
53
494
  vector_rem2(&s->shreds, (vtype)tk->self);
54
494
}
55
56
505
ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase) {
57
505
  MUTEX_LOCK(s->mutex);
58
505
  struct ShredTick_ *tk = out->tick;
59
505
  if(tk == s->curr)
60
482
    s->curr = NULL;
61
23
  else if(tk == s->list)
62
7
    s->list = tk->next;
63
505
  if(tk->prev)
64
15
    tk->prev->next = tk->next;
65
505
  if(tk->next)
66
5
    tk->next->prev = tk->prev;
67
505
  tk->prev = tk->next = NULL;
68
505
  if(erase) {
69
494
    shreduler_erase(s, tk);
70
494
    _release(out->info->me, out);
71
  }
72
505
  MUTEX_UNLOCK(s->mutex);
73
505
}
74
75
661
ANN void shredule(const Shreduler s, const VM_Shred shred, const m_float wake_time) {
76
661
  const m_float time = wake_time + (m_float)s->bbq->pos;
77
661
  struct ShredTick_ *tk = shred->tick;
78
661
  tk->wake_time = time;
79
661
  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
483
    s->list = tk;
97
661
  if(tk == s->curr)
98
154
    s->curr = NULL;
99
661
}
100
101
1211
ANN void shreduler_ini(const Shreduler s, const VM_Shred shred) {
102
1211
  shred->tick = mp_calloc(shred->info->mp, ShredTick);
103
1211
  shred->tick->self = shred;
104
1211
  shred->tick->shreduler = s;
105
1211
}
106
107
497
ANN void shreduler_add(const Shreduler s, const VM_Shred shred) {
108
497
  shreduler_ini(s, shred);
109
497
  shred->tick->xid = ++s->shred_ids;
110
497
  vector_add(&s->shreds, (vtype)shred);
111
497
  shredule(s, shred, GWION_EPSILON);
112
497
}