Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <stdio.h> | ||
2 | #include <assert.h> | ||
3 | |||
4 | #include <powertask/scheduler.h> | ||
5 | #include <powertask/energy.h> | ||
6 | #include <powertask/storage.h> | ||
7 | |||
8 | #define TASK_SCHEDULER_MAX_NUMBER_OF_TASKS 255 | ||
9 | #define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) | ||
10 | |||
11 | /** @brief Current scheduler state*/ | ||
12 | struct current_state_s { | ||
13 | bool tasks_state[TASK_SCHEDULER_MAX_NUMBER_OF_TASKS]; /**< Array containing current task states. */ | ||
14 | int number_of_tasks; /**< Number of valid elements in tasks_state. */ | ||
15 | }; | ||
16 | |||
17 | /* ------------------------------------------------------------------------------------------------------------------ */ | ||
18 | /* Private API */ | ||
19 | /* ------------------------------------------------------------------------------------------------------------------ */ | ||
20 | |||
21 | 6 | static void reset_current_state(powertask_scheduler *sched){ | |
22 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | for(int i = 0; i < sched->number_of_tasks; i++){ |
23 | 8 | sched->list_of_tasks[i]->complete = false; | |
24 | } | ||
25 | 6 | } | |
26 | |||
27 | 14 | static void save_current_state(powertask_scheduler *sched){ | |
28 | struct current_state_s to_save; | ||
29 | |||
30 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
|
14 | if(sched->number_of_tasks > ARRAY_LENGTH(to_save.tasks_state)){ |
31 | /* TODO: Review this behaviour. Does it make sense to simply not | ||
32 | * store the current state? This changes the expected behaviour of the | ||
33 | * program. | ||
34 | */ | ||
35 | 1 | return; | |
36 | } | ||
37 | |||
38 | 13 | to_save.number_of_tasks = sched->number_of_tasks; | |
39 | |||
40 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 13 times.
|
33 | for(int i = 0; i < sched->number_of_tasks; i++){ |
41 | 20 | to_save.tasks_state[i] = sched->list_of_tasks[i]->complete; | |
42 | } | ||
43 | |||
44 | 13 | powertask_storage_save(&to_save, sizeof(struct current_state_s)); | |
45 | } | ||
46 | |||
47 | 14 | static void load_current_state(powertask_scheduler *sched){ | |
48 | 14 | int err = 0; | |
49 | struct current_state_s loaded; | ||
50 | |||
51 | 14 | err = powertask_storage_load(&loaded, sizeof(struct current_state_s)); | |
52 | |||
53 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
14 | if(err < 0){ |
54 | 13 | return; | |
55 | } | ||
56 | |||
57 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if(loaded.number_of_tasks > sched->_list_of_tasks_len){ |
58 | 1 | return; | |
59 | } | ||
60 | |||
61 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | for(int i = 0; i < loaded.number_of_tasks; i++){ |
62 | 2 | sched->list_of_tasks[i]->complete = loaded.tasks_state[i]; | |
63 | } | ||
64 | } | ||
65 | |||
66 | /* ------------------------------------------------------------------------------------------------------------------ */ | ||
67 | /* Public API */ | ||
68 | /* ------------------------------------------------------------------------------------------------------------------ */ | ||
69 | |||
70 | 277 | void powertask_add(powertask_scheduler *sched, powertask_task *task){ | |
71 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 276 times.
|
277 | if(sched->number_of_tasks >= sched->_list_of_tasks_len){ |
72 | 1 | return; | |
73 | } | ||
74 | 276 | sched->list_of_tasks[sched->number_of_tasks++] = task; | |
75 | 276 | return; | |
76 | } | ||
77 | |||
78 | 17 | void powertask_run_scheduler(powertask_scheduler *sched, powertask_energy_source_t *energy_source){ | |
79 | |||
80 | 17 | int i = 0; | |
81 | 17 | int complete_tasks = 0; | |
82 | powertask_task *current_task; | ||
83 | |||
84 |
4/4✓ Branch 0 taken 15 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 14 times.
|
17 | if(sched == NULL || energy_source == NULL){ |
85 | 3 | return; | |
86 | } | ||
87 | |||
88 | 14 | load_current_state(sched); | |
89 | |||
90 |
2/2✓ Branch 0 taken 276 times.
✓ Branch 1 taken 14 times.
|
290 | for(;i < sched->number_of_tasks; i++){ |
91 | 276 | current_task = sched->list_of_tasks[i]; | |
92 | |||
93 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 275 times.
|
276 | if(current_task->complete){ |
94 | 1 | complete_tasks++; | |
95 | 1 | continue; | |
96 | } | ||
97 | |||
98 | 275 | int available_energy = powertask_get_available_energy(energy_source); | |
99 | |||
100 |
2/2✓ Branch 0 taken 258 times.
✓ Branch 1 taken 17 times.
|
275 | if(available_energy <= current_task->required_energy){ |
101 | 258 | continue; | |
102 | } | ||
103 | |||
104 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 times.
|
17 | if(current_task->condition != NULL) { |
105 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 10 times.
|
16 | if(!current_task->condition()){ |
106 | 6 | continue; | |
107 | } | ||
108 | } | ||
109 | |||
110 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
|
11 | if(current_task->action != NULL){ |
111 | 10 | current_task->action(); | |
112 | } | ||
113 | |||
114 | 11 | current_task->complete = true; | |
115 | 11 | complete_tasks++; | |
116 | } | ||
117 | |||
118 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
|
14 | if(complete_tasks == sched->number_of_tasks){ |
119 | 6 | reset_current_state(sched); | |
120 | } | ||
121 | |||
122 | 14 | save_current_state(sched); | |
123 | } | ||
124 |