]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres_analysis.c
00d5fe61cc1278684e27a682e89345a7693e48b7
[frescor/fna.git] / src_frescan / frescan_bwres_analysis.c
1 /*!
2  * @file frescan_bwres_analysis.c
3  *
4  * @brief FRESCAN bandwith reservation layer: sched analysis
5  *
6  * This module contains the scheduling analysis data and functions for the
7  * admission tests and spare capacity distribution of the negotiation layer.
8  * It provides an easy API easy to understand and in the implementation part
9  * it makes call to the general sched analysis module of FRSH which is shared
10  * with the CPU contracts layer in FRSH.
11  *
12  * EXAMPLE of utilization:
13  *
14  * INITIALIZATION
15  * --------------
16  * params.min_prio = 0;
17  * params.max_prio = 16;
18  * params.overhead = ...;
19  * frescan_sa_init(&scenario, &params);
20  *
21  * NEGOTIATE
22  * ---------
23  * fadt_freelist_alloc(&freelist_contracts, &id);
24  * frescan_sa_add_contract(&scenario, &contracts[id], id);
25  * frescan_sa_sched_test(&scenario, &success);
26  *
27  * if (!success) {
28  *      frescan_sa_remove_contract(&scenario, id);
29  * } else {
30  *      frescan_sa_spare_capacity(&scenario);
31  *      vres_id = to_vres(resource_type, resource_id, id);
32  *      create vres runtime structures;
33  *
34  *      for vres_id in active_vres_id {
35  *                frescan_sa_get_final_values(&scenario,
36  *                                            to_index(vres_id),
37  *                                            &final_values);
38  *                update vres runtime structures if necessary;
39  *      }
40  * }
41  *
42  * RENEGOTIATE
43  * -----------
44  * copy old_contract
45  * frescan_sa_update_contract(&scenario, to_index(vres_id), &contract);
46  * frescan_sa_sched_test(&scenario, &success);
47  *
48  * if (!success) {
49  *         frescan_sa_update_contract(&sa_data,
50  *                                    to_index(vres_id),
51  *                                    &old_contract);
52  * } else {
53  *      frescan_sa_spare_capacity(&scenario);
54  *      for vres_id in active_vres_id {
55  *              frescan_sa_get_final_values(&scenario,
56  *                                          to_index(vres_id),
57  *                                          &final_values);
58  *              update vres runtime structures if necessary;
59  *      }
60  * }
61  *
62  * CANCEL
63  * ------
64  * frescan_sa_remove_contract(&scenario, to_index(vres_id));
65  * frescan_sa_spare_capacity(&scenario);
66  *
67  * @version 0.01
68  *
69  * @date 15-Apr-2008
70  *
71  * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
72  *
73  */
74
75 #include <math.h>
76 #include <misc/timespec_operations.h>
77 #include "frescan_bwres_analysis.h"
78 #undef ERROR
79 #include "frescan_debug.h"
80
81 /**
82  * frescan_sa_init() - init the scenario
83  *
84  * @scenario: the scenario (in out)
85  * @params: init params (in)
86  */
87
88 int frescan_sa_init(frescan_sa_scenario_t *scenario,
89                     const frescan_sa_init_params_t *params)
90 {
91 //         int ret;
92 //
93 //         ret = frsh_sa_scenario_init(scenario, params);
94 //         return ret;
95
96         INIT_LIST_HEAD(&scenario->contracts_head.list);
97         scenario->init_params = *params;
98         return 0;
99 }
100
101 /**
102  * frescan_sa_add_contract() - add a contract to the scenario
103  *
104  * @scenario: the scenario (in out)
105  * @contract: the new contract (in)
106  * @ss: the preallocated ss identificator (in)
107  * @node: the node this contract belongs to (in)
108  */
109
110 int frescan_sa_add_contract(frescan_sa_scenario_t    *scenario,
111                             const frescan_contract_t *contract,
112                             frescan_ss_t             ss,
113                             frescan_node_t           node)
114 {
115 //         int ret;
116 //
117 //         ret = frsh_sa_scenario_add_vres(scenario, contract, id);
118 //         return ret;
119         frescan_sa_contract_t *sa_contract;
120
121         sa_contract = &scenario->contracts[node][ss];
122
123         sa_contract->contract = *contract;
124         sa_contract->node     = node;
125         sa_contract->ss       = ss;
126
127         list_add_tail(&sa_contract->list,
128                       &scenario->contracts_head.list);
129
130         return 0;
131 }
132
133 /**
134  * frescan_sa_update_contract() - update a contract in the scenario
135  *
136  * @scenario: the scenario (in out)
137  * @ss: the ss identificator (in)
138  * @node: the node this contract belongs to (in)
139  * @contract: the values to update the contract (in)
140  * @old_contract: the values of the previous contract. Can be NULL (out)
141  */
142
143 int frescan_sa_update_contract(frescan_sa_scenario_t   *scenario,
144                                frescan_ss_t             ss,
145                                frescan_node_t           node,
146                                const frescan_contract_t *contract,
147                                frescan_contract_t       *old_contract)
148 {
149 //         int ret;
150 //
151 //         ret = frsh_sa_scenario_modify_vres(scenario, id, *contract);
152 //         return ret;
153         frescan_sa_contract_t *sa_contract;
154
155         sa_contract = &scenario->contracts[node][ss];
156
157         if (old_contract != NULL) {
158                 *old_contract = sa_contract->contract;
159         }
160
161         sa_contract->contract = *contract;
162
163         return 0;
164 }
165
166 /**
167  * frescan_sa_remove_contract() - remove a contract from the scenario
168  *
169  * @scenario: the scenario (in out)
170  * @ss: the ss to remove (in)
171  * @node: the node this contract belongs to (in)
172  */
173
174 int frescan_sa_remove_contract(frescan_sa_scenario_t *scenario,
175                                frescan_ss_t          ss,
176                                frescan_node_t        node)
177 {
178 //         int ret;
179 //
180 //         ret = frsh_sa_scenario_del_vres(scenario, id);
181 //         return ret;
182         frescan_sa_contract_t *sa_contract;
183
184         sa_contract = &scenario->contracts[node][ss];
185         list_del(&sa_contract->list);
186
187         return 0;
188 }
189
190 /**
191  * frescan_sa_sched_test() - perform a scheduling test on the scenario
192  *
193  * @scenario: the scenario (in out)
194  * @success: if the scenario is schedulable or not (out)
195  */
196
197 int frescan_sa_sched_test(frescan_sa_scenario_t *scenario,
198                           bool *success)
199 {
200 //         int ret;
201 //
202 //         ret = frsh_sa_scenario_reset_to_min(scenario, NULL, NULL);
203 //         if (ret != 0) goto error;
204 //
205 //         ret = frsh_sa_assign_priorities(scenario, NULL, NULL, NULL, NULL);
206 //         if (ret != 0) goto error;
207 //
208 //         ret = frsh_sa_ceilings_ok(scenario);
209 //         if (ret != 0) goto error;
210 //
211 //         ret = frsh_sa_calculate_blockings(scenario);
212 //         if (ret != 0) goto error;
213 //
214 //         ret = frsh_sa_sched_test(scenario, success);
215 //         if (ret != 0) goto error;
216 //
217 //         return 0;
218 //
219 // error:
220 //         *success = false;
221 //         return ret;
222
223         struct list_head *pos;
224         frescan_sa_contract_t *sa_contract;
225         int num_contracts;
226         double utilization, max_utilization, budget, period;
227
228         WARNING("simplified ub test (no blocks, prio ordered)\n");
229
230         utilization = 0.0;
231         num_contracts = 0;
232
233         list_for_each(pos, &scenario->contracts_head.list) {
234                 sa_contract = list_entry(pos, frescan_sa_contract_t, list);
235                 sa_contract->final_values.server_prio = sa_contract->contract.prio;
236
237                 budget = (double)sa_contract->contract.min_values.budget *
238                          (double)FRESCAN_FRAME_TX_TIME;
239
240                 period = timespec_to_double
241                                 (&sa_contract->contract.min_values.period);
242
243                 utilization = utilization + (budget / period);
244
245                 num_contracts++;
246
247                 DEBUG(FRESCAN_SA_ENABLE_DEBUG,
248                       "sa_contract, node:%d ss:%d, c:%d t:(%d,%d) p:%d\n",
249                       sa_contract->node, sa_contract->ss,
250                       sa_contract->contract.min_values.budget,
251                       sa_contract->contract.min_values.period.tv_sec,
252                       sa_contract->contract.min_values.period.tv_nsec,
253                       sa_contract->contract.prio);
254         }
255
256         max_utilization = num_contracts *
257                           (pow(2.0, 1.0/(double)num_contracts) - 1);
258
259         DEBUG(FRESCAN_SA_ENABLE_DEBUG, "u:%f n:%d u_max:%f %s\n",
260               utilization, num_contracts, max_utilization,
261               (utilization < max_utilization) ? "accepted" : "not accepted");
262
263         if (utilization < max_utilization) {
264                 *success = true;
265         } else {
266                 *success = false;
267         }
268
269         return 0;
270 }
271
272 /**
273  * frescan_sa_spare_capacity() - distribute the remaining spare capacity
274  *
275  * @scenario: the scenario (in out)
276  */
277
278 int frescan_sa_spare_capacity(frescan_sa_scenario_t *scenario)
279 {
280 //         int ret;
281 //
282 //         ret = frsh_sa_distribute_spare(scenario,
283 //                                        NULL, NULL, NULL, NULL, NULL, NULL);
284 //         return ret;
285         WARNING("not implemented, returning 0\n");
286         return 0;
287 }
288
289 /**
290  * frescan_sa_get_final_values() - get the final values
291  *
292  * @scenario: the scenario (in)
293  * @ss: the ss from which we want the final values (in)
294  * @node: the node this contract belongs to (in)
295  * @final_values: the final values (out)
296  */
297
298
299 int frescan_sa_get_final_values(const frescan_sa_scenario_t *scenario,
300                                 frescan_ss_t              ss,
301                                 frescan_node_t            node,
302                                 frescan_sa_final_values_t *final_values)
303 {
304 //         final_values->budget   = scenario->sa_vres_alloc[id].c;
305 //         final_values->period   = scenario->sa_vres_alloc[id].t;
306 //         final_values->deadline = scenario->sa_vres_alloc[id].d;
307 //         final_values->priority = scenario->sa_vres_alloc[id].p;
308 //         return 0;
309
310         *final_values = scenario->contracts[node][ss].final_values;
311
312         return 0;
313 }