GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/vm/shreduler.c Lines: 85 85 100.0 %
Date: 2020-09-14 09:03:05 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
5801919
ANN VM_Shred shreduler_get(const Shreduler s) {
15
5801919
  Driver *const bbq = s->bbq;
16
5801919
  struct ShredTick_ *const tk = s->list;
17
5801919
  if(!tk) {
18

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