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

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