-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathp2G4_func_queue.c
98 lines (85 loc) · 2.18 KB
/
p2G4_func_queue.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
* Copyright 2018 Oticon A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "p2G4_func_queue.h"
#include "bs_oswrap.h"
#include "bs_tracing.h"
/*
* Array with one element per device interface
* Each interface can have 1 function pending
*/
static fq_element_t *f_queue = NULL;
static uint32_t next_d = 0;
static uint32_t n_devs = 0;
static queable_f fptrs[N_funcs];
void fq_init(uint32_t n_dev){
f_queue = bs_calloc(n_dev, sizeof(fq_element_t));
n_devs = n_dev;
for (int i = 0 ; i < n_devs; i ++) {
f_queue[i].time = TIME_NEVER;
f_queue[i].f_index = State_None;
}
}
void fq_register_func(f_index_t type, queable_f fptr) {
fptrs[type] = fptr;
}
/**
* Find the next function which should be executed,
* Based on the following order, from left to right:
* time (lower first), function index (higher first), device number (lower first)
* TOOPT: The whole function queue is implemented in a simple/naive way,
* which is perfectly fine for simulations with a few devices.
* But, if there is many devices, this would be quite slow.
*/
void fq_find_next(){
bs_time_t chosen_f_time;
next_d = 0;
chosen_f_time = f_queue[0].time;
for (int i = 1; i < n_devs; i ++) {
fq_element_t *el = &f_queue[i];
if (el->time < chosen_f_time) {
next_d = i;
chosen_f_time = el->time;
continue;
} else if (el->time == chosen_f_time) {
if (el->f_index > f_queue[next_d].f_index) {
next_d = i;
continue;
}
}
}
}
/**
* Add a function for dev_nbr to the queue and reorder it
*/
void fq_add(bs_time_t time, f_index_t index, uint32_t dev_nbr) {
fq_element_t *el = &f_queue[dev_nbr];
el->time = time;
el->f_index = index;
}
/**
* Remove an element from the queue and reorder it
*/
void fq_remove(uint32_t d){
f_queue[d].f_index = State_None;
f_queue[d].time = TIME_NEVER;
}
/**
* Call the next function in the queue
* Note: The function itself is left in the queue.
*/
void fq_call_next(){
fptrs[f_queue[next_d].f_index](next_d);
}
/**
* Get the time of the next element of the queue
*/
bs_time_t fq_get_next_time(){
return f_queue[next_d].time;
}
void fq_free(){
if ( f_queue != NULL )
free(f_queue);
}