]> rtime.felk.cvut.cz Git - frescor/frsh.git/blob - frsh_api/frsh_power.c
56381090975f2114270a0c1fa2eabaa426b5c104
[frescor/frsh.git] / frsh_api / frsh_power.c
1 /**
2  * @file   frsh_power.c
3  * @author Michael Trimarchi <trimarchimichael@yahoo.it>
4  *         Dario Faggioli <faggioli@gandalf.sssup.it>
5  *
6  * @brief  FRSH core thread related functions not implamented in managers..
7  *
8  *
9  */
10
11 #include <string.h>
12
13 #include <fres_contract.h>
14 #include <fres_contract_idl.h>
15 #include <fres_blocks.h>
16 #include <fcb.h>
17 #include <fra_generic.h>
18 #include <frsh_forb.h>
19 #include <fra_acpi_cpu.h>
20 #include <fra_acpi_lcd.h>
21 #include <frsh.h>
22
23 static inline int __is_a_valid_power(level)
24 {
25         if (level >=0 && level < 3 )
26                 return 1;
27
28         return 0;
29 }
30
31 int frsh_contract_set_min_expiration(frsh_contract_t *contract,
32                                      frsh_rel_time_t min_expiration)
33 {
34         fres_block_power_management *p;
35         int ret;
36
37         if (!contract || !*contract)
38                 return FRSH_ERR_BAD_ARGUMENT;
39
40         p = fres_contract_get_power_management(*contract);
41         if (!p) {
42                 p = malloc(sizeof(*p));
43                 if (!p) return ENOMEM;
44         }
45         p->min_expiration = min_expiration;
46
47         fres_contract_del_power_management(*contract);
48         ret = fres_contract_add_power_management(*contract, p);
49         if (ret) {
50                 free(p);
51                 return errno;
52         }
53
54         return FRSH_NO_ERROR;
55 }
56
57 int frsh_contract_set_min_budget_pow
58   (frsh_contract_t *contract,
59    frsh_power_level_t power_level,
60    const frsh_rel_time_t *pow_min_budget)
61 {
62         fres_block_power_management *b;
63         int ret;
64
65         if (!contract || !*contract ||
66             !pow_min_budget)
67                 return FRSH_ERR_BAD_ARGUMENT;
68
69         b = fres_contract_get_power_management(*contract);
70         if (!b) {
71                 b = malloc(sizeof(*b));
72                 if (!b) return ENOMEM;
73         }
74         b->min_budget[power_level] = *pow_min_budget;
75
76         fres_contract_del_power_management(*contract);
77         ret = fres_contract_add_power_management(*contract, b);
78         if (ret) {
79                 free(b);
80                 return errno;
81         }
82
83         return FRSH_NO_ERROR;
84 }
85
86 int frsh_contract_get_min_budget_pow
87   (const frsh_contract_t *contract,
88    frsh_power_level_t power_level,
89    frsh_rel_time_t *pow_min_budget)
90 {
91         fres_block_power_management *b;
92
93         if (!contract || !*contract ||
94             !__is_a_valid_power(power_level))
95                 return FRSH_ERR_BAD_ARGUMENT;
96
97         b = fres_contract_get_power_management(*contract);
98         if (!b)
99                 return FRSH_ERR_BAD_ARGUMENT;
100
101         *pow_min_budget = b->min_budget[power_level];
102
103         return FRSH_NO_ERROR;
104 }
105
106 int frsh_contract_set_max_budget_pow
107   (frsh_contract_t *contract,
108    frsh_power_level_t power_level,
109    const frsh_rel_time_t *pow_max_budget)
110 {
111         fres_block_power_management *b;
112         int ret;
113
114         if (!contract || !*contract ||
115             !pow_max_budget || !__is_a_valid_power(power_level))
116                 return FRSH_ERR_BAD_ARGUMENT;
117
118         b = fres_contract_get_power_management(*contract);
119         if (!b) {
120                 b = malloc(sizeof(*b));
121                 if (!b) return ENOMEM;
122         }
123         b->max_budget[power_level] = *pow_max_budget;
124
125         fres_contract_del_power_management(*contract);
126         ret = fres_contract_add_power_management(*contract, b);
127         if (ret) {
128                 free(b);
129                 return errno;
130         }
131
132         return FRSH_NO_ERROR;
133 }
134
135 int frsh_contract_get_max_budget_pow(const frsh_contract_t *contract,
136                                      frsh_power_level_t power_level,
137                                      frsh_rel_time_t *pow_max_budget)
138 {
139         fres_block_power_management *b;
140
141         if (!contract || !*contract ||
142             !__is_a_valid_power(power_level)) {
143                 return FRSH_ERR_BAD_ARGUMENT;
144         }
145
146         b = fres_contract_get_power_management(*contract);
147         if (!b)
148                 return FRSH_ERR_BAD_ARGUMENT;
149
150         *pow_max_budget = b->max_budget[power_level];
151
152         return FRSH_NO_ERROR;
153 }
154
155 int frsh_contract_set_utilization_pow
156   (frsh_contract_t *contract,
157    frsh_power_level_t power_level,
158    const frsh_rel_time_t *budget,
159    const frsh_rel_time_t *period,
160    const frsh_rel_time_t *deadline)
161 {
162         return FRSH_ERR_NOT_IMPLEMENTED;
163 }
164
165 int frsh_contract_get_utilization_pow
166   (const frsh_contract_t *contract,
167    frsh_power_level_t power_level,
168    frsh_rel_time_t *budget,
169    frsh_rel_time_t *period,
170    frsh_rel_time_t *deadline)
171 {
172         return FRSH_ERR_NOT_IMPLEMENTED;;
173 }
174
175 int frsh_resource_set_power_level
176   (frsh_resource_type_t resource_type,
177    frsh_resource_id_t resource_id,
178    frsh_power_level_t power_level)
179 {
180         int ret;
181
182         switch(resource_type)
183         {
184                 case FRSH_RT_PROCESSOR:
185                 {
186                         ret = fra_CPU_frequency_init(resource_id);
187                         if (ret) goto err;
188
189                         ret = fra_CPU_set_frequency(resource_id, power_level);
190                         if (ret) goto err;
191
192                         /**
193                          * @TODO:
194                          * if (i budget sono effettivamente diversi)
195                          *      rinegozia i contratti coi nuovi valori
196                          **/
197         
198                         break;
199                 }
200                 case FRSH_RT_LCD:
201                 {
202                         ret = fra_LCD_brightness_init(resource_id);
203                         if (ret) goto err;
204
205                         ret = fra_LCD_set_brightness(resource_id, power_level);
206                         if (ret) goto err;
207
208                         break;
209                 }
210                 default:
211                         return FRSH_ERR_NOT_IMPLEMENTED;
212         }
213
214         return FRSH_NO_ERROR;
215 err:
216         return FRSH_ERR_INTERNAL_ERROR;
217 }
218
219 int frsh_resource_get_power_level
220   (frsh_resource_type_t resource_type,
221    frsh_resource_id_t resource_id,
222    frsh_power_level_t *power_level)
223 {
224         int ret;
225
226         switch(resource_type)
227         {
228                 case FRSH_RT_PROCESSOR:
229                 {
230                         ret = fra_CPU_get_level(resource_id,
231                                                 (int*) power_level);
232                         if (ret) goto err;
233
234                         break;
235                 }
236                 case FRSH_RT_LCD:
237                 {
238                         ret = fra_LCD_get_level(resource_id,
239                                                 (int*) power_level);
240                         if (ret) goto err;
241
242                         break;
243                 }
244                 default:
245                         return FRSH_ERR_NOT_IMPLEMENTED;
246         }
247
248         return FRSH_NO_ERROR;
249 err:
250         return FRSH_ERR_INTERNAL_ERROR;
251 }
252
253 int frsh_resource_get_num_power_levels
254   (frsh_resource_type_t resource_type,
255    frsh_resource_id_t resource_id,
256    frsh_power_level_t *num_power_levels)
257 {
258         /**
259          * @FIXME:
260          *   This looks tremendous... But the number '3' is hardcoded
261          *   whereever in the headers as the number of power level, so...
262          */
263         *num_power_levels = 3;
264
265         return FRSH_NO_ERROR;
266 }
267
268 int frsh_battery_get_expiration(frsh_abs_time_t *expiration)
269 {
270         frsh_rel_time_t interval;
271         int ret;
272
273         ret = fra_CPU_battery_expiration(&interval);
274         if (ret) return FRSH_ERR_INTERNAL_ERROR;
275
276         fosa_clock_get_time(FOSA_CLOCK_REALTIME, expiration);
277         *expiration = fosa_abs_time_incr(*expiration, interval);
278
279         return FRSH_NO_ERROR;
280 }
281