]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres.c
add debugging message
[frescor/fna.git] / src_frescan / frescan_bwres.c
1 /*!
2  * @file frescan_bwres.c
3  *
4  * @brief FRESCAN bandwidth reservation layer
5  *
6  * This module contains function to negotiate contracts and get the
7  * corresponding frescan sporadic servers.
8  *
9  * @version 0.01
10  *
11  * @date 1-Apr-2008
12  *
13  * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
14  *
15  * @license
16  *
17  * -----------------------------------------------------------------------
18  *  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
19  *
20  *    Universidad de Cantabria,              SPAIN
21  *    University of York,                    UK
22  *    Scuola Superiore Sant'Anna,            ITALY
23  *    Kaiserslautern University,             GERMANY
24  *    Univ. Politécnica  Valencia,           SPAIN
25  *    Czech Technical University in Prague,  CZECH REPUBLIC
26  *    ENEA                                   SWEDEN
27  *    Thales Communication S.A.              FRANCE
28  *    Visual Tools S.A.                      SPAIN
29  *    Rapita Systems Ltd                     UK
30  *    Evidence                               ITALY
31  *
32  *    See http://www.frescor.org for a link to partners' websites
33  *
34  *           FRESCOR project (FP6/2005/IST/5-034026) is funded
35  *        in part by the European Union Sixth Framework Programme
36  *        The European Union is not liable of any use that may be
37  *        made of this code.
38  *
39  *  This file is part of FRESCAN
40  *
41  *  FRESCAN is free software; you can  redistribute it and/or  modify
42  *  it under the terms of  the GNU General Public License as published by
43  *  the Free Software Foundation;  either  version 2, or (at  your option)
44  *  any later version.
45  *
46  *  FRESCAN  is distributed  in  the hope  that  it  will  be useful,  but
47  *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
48  *  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
49  *  General Public License for more details.
50  *
51  *  You should have  received a  copy of  the  GNU  General Public License
52  *  distributed  with  FRESCAN;  see file COPYING.   If not,  write to the
53  *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
54  *  02111-1307, USA.
55  *
56  * As a special exception, including FRESCAN header files in a file,
57  * instantiating FRESCAN generics or templates, or linking other files
58  * with FRESCAN objects to produce an executable application, does not
59  * by itself cause the resulting executable application to be covered
60  * by the GNU General Public License. This exception does not
61  * however invalidate any other reasons why the executable file might be
62  * covered by the GNU Public License.
63  * -----------------------------------------------------------------------
64  *
65  */
66
67 #include "frsh.h"
68 #include "frescan_bwres.h"
69 #include "frescan_bwres_requests.h"
70 #include "frescan_bwres_robjs.h"
71 #include "frescan_bwres_messages.h"
72 #include "frescan_bwres_threads.h"
73 #include "frescan_bwres_analysis.h"
74 #include "frescan_data.h"
75 #include "frescan_debug.h"
76 #include "frescan_config.h"
77 #include "frescan_servers.h"
78
79 /**
80  * frescan_bwres_init()
81  *
82  * Init the frescan bandwidth reservation layer
83  */
84
85 int frescan_bwres_init(frescan_network_t net)
86 {
87         int ret;
88         frescan_node_t node;
89         frescan_ss_t neg_msg_ss_id;
90         frescan_server_params_t server_params;
91         frescan_bwres_sa_init_params_t init_params;
92         frsh_contract_t neg_msgs_contract;
93         frsh_rel_time_t neg_msgs_budget;
94         frsh_rel_time_t neg_msgs_period;
95
96         init_params.min_prio = FRESCAN_BWRES_SS_MIN_PRIO;
97         init_params.max_prio = FRESCAN_BWRES_SS_MAX_PRIO;
98
99         if (frescan_data[net].local_node == FRESCAN_BWRES_MASTER_NODE) {
100             ret = frescan_bwres_sa_init(&frescan_data[net].scenario,
101                                         &init_params);
102             if (ret != 0) return ret;
103
104             // Add contracts for the negotiation messages
105             ret = frsh_contract_init(&neg_msgs_contract);
106             if (ret != 0) return ret;
107
108             neg_msgs_budget = frsh_usec_to_rel_time(
109                                         (long)FRESCAN_FRAME_TX_TIME_US *
110                                               FRESCAN_BWRES_NEG_MSG_BUDGET);
111
112             neg_msgs_period = frsh_usec_to_rel_time(
113                                         (long)FRESCAN_BWRES_NEG_MSG_PERIOD);
114
115             ret = frsh_contract_set_basic_params(&neg_msgs_contract,
116                                                  &neg_msgs_budget,
117                                                  &neg_msgs_period,
118                                                  FRSH_WT_INDETERMINATE,
119                                                  FRSH_CT_REGULAR);
120             if (ret != 0) return ret;
121
122             ret = frsh_contract_set_preemption_level
123                             (&neg_msgs_contract, FRESCAN_BWRES_NEG_MSG_PRIO);
124             if (ret != 0) return ret;
125
126             for(node=0; node<FRESCAN_MX_NODES; node++) {
127                     ret = freelist_init(&frescan_data[net].scenario.
128                                                         ss_id_freelist[node],
129                                                         FRESCAN_MX_IDS);
130                     if (ret != 0) return ret;
131
132                     ret = freelist_alloc(&frescan_data[net].scenario.
133                                                         ss_id_freelist[node]);
134                     if (ret < 0) return -1;
135
136                     neg_msg_ss_id = (frescan_ss_t)ret;
137
138                     DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
139                           "manager contract node:%u b:(%d,%d) t:(%d,%d) p:%u\n",
140                           node,
141                           neg_msgs_budget.tv_sec, neg_msgs_budget.tv_nsec,
142                           neg_msgs_period.tv_sec, neg_msgs_period.tv_nsec,
143                           FRESCAN_BWRES_NEG_MSG_PRIO);
144
145                     ret = frescan_bwres_sa_add_contract
146                                     (&frescan_data[net].scenario,
147                                      neg_msg_ss_id,
148                                      node,
149                                      &neg_msgs_contract);
150                     if (ret != 0) return ret;
151             }
152         }
153
154         server_params.budget = FRESCAN_BWRES_NEG_MSG_BUDGET;
155         server_params.period = frsh_rel_time_to_timespec(
156                                         frsh_usec_to_rel_time(
157                                         (long)FRESCAN_BWRES_NEG_MSG_PERIOD));
158         server_params.prio   = FRESCAN_BWRES_NEG_MSG_PRIO;
159
160         ret = frescan_servers_create(net, &server_params,
161                                      &frescan_data[net].neg_messages_ss_id);
162         if (ret != 0) return ret;
163
164         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "neg_msg_ss_id: %u\n",
165               frescan_data[net].neg_messages_ss_id);
166
167         ret = frescan_bwres_robjs_init(FRESCAN_BWRES_ROBJS_MX_CEILING);
168         if (ret != 0) return ret;
169
170         ret = frescan_bwres_requests_init(FRESCAN_BWRES_REQ_MX_CEILING);
171         if (ret != 0) return ret;
172
173         ret = frescan_messages_init(net);
174         if (ret != 0) return ret;
175
176         ret = frescan_manager_thread_create(net);
177         if (ret != 0) return ret;
178
179         ret = frescan_acceptor_thread_create(net);
180         if (ret != 0) return ret;
181
182         return 0;
183 }
184
185 /**
186  * frescan_bwres_group_change_mode_sync()
187  *
188  * 1.- allocate and prepare the GN request
189  * 2.- enqueue the request
190  * 3.- wait in the reply object for a reply
191  *     (unless there are only cancellations)
192  * 4.- free the request
193  */
194
195 int frescan_bwres_group_change_mode_sync
196                 (frescan_network_t            net,
197                  const frsh_contracts_group_t *contracts_to_neg,
198                  const frsh_contracts_group_t *contracts_to_reneg,
199                  const frescan_ss_group_t     *ss_to_reneg,
200                  const frescan_ss_group_t     *ss_to_cancel,
201                  frescan_ss_group_t           *ss_new,
202                  bool                         *accepted)
203 {
204         int ret;
205         frescan_bwres_request_id_t req;
206         frescan_bwres_request_data_t *req_data;
207
208         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a GN request\n");
209
210         ret = frescan_bwres_requests_alloc(&req);
211         if (ret != 0) return ret;
212
213         ret = frescan_bwres_requests_get_data(req, &req_data);
214         if (ret != 0) return ret;
215
216         req_data->net          = net;
217         req_data->type         = FRESCAN_BWRES_REQ_GN;
218         req_data->req          = req;
219         req_data->request_node = frescan_data[net].local_node;
220
221         if (contracts_to_neg == NULL) {
222                 req_data->contracts_to_neg = &req_data->contracts_to_neg_data;
223                 req_data->contracts_to_neg->size = 0;
224         } else {
225                 req_data->contracts_to_neg =
226                                 (frsh_contracts_group_t *)contracts_to_neg;
227         }
228
229         if (contracts_to_reneg == NULL) {
230                 req_data->contracts_to_reneg = &req_data->
231                                                        contracts_to_reneg_data;
232                 req_data->contracts_to_reneg->size = 0;
233         } else {
234                 req_data->contracts_to_reneg = (frsh_contracts_group_t *)
235                                 contracts_to_reneg;
236         }
237
238         if (ss_to_reneg == NULL) {
239                 req_data->ss_to_reneg = &req_data->ss_to_reneg_data;
240                 req_data->ss_to_reneg->size = 0;
241         } else {
242                 req_data->ss_to_reneg = (frescan_ss_group_t *)ss_to_reneg;
243         }
244
245         if (ss_to_cancel == NULL) {
246                 req_data->ss_to_cancel = &req_data->ss_to_cancel_data;
247                 req_data->ss_to_cancel->size = 0;
248         } else {
249                 req_data->ss_to_cancel = (frescan_ss_group_t *)ss_to_cancel;
250
251         }
252
253         if (ss_new == NULL) {
254                 req_data->ss_new = &req_data->ss_new_data;
255                 req_data->ss_new->size = 0;
256         } else {
257                 req_data->ss_new = ss_new;
258         }
259
260         ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
261         if (ret != 0) return ret;
262
263         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue the negotiation request\n");
264
265         ret = frescan_bwres_requests_enqueue(req);
266         if (ret != 0) return ret;
267
268         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
269
270         ret = frescan_bwres_robjs_wait(req_data->robj);
271         if (ret != 0) return ret;
272
273         ret = frescan_bwres_robjs_free(req_data->robj);
274         if (ret != 0) return ret;
275
276         switch (req_data->return_value) {
277                 case FRESCAN_BWRES_REQ_ACCEPTED:
278                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n");
279                         *accepted = true;
280                         break;
281
282                 case FRESCAN_BWRES_REQ_NOT_ACCEPTED:
283                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation FAIL\n");
284                         *accepted = false;
285                         break;
286
287                 default:
288                         FRESCAN_ERROR("return_value unknown\n");
289                         return -1;
290         }
291
292         ret = frescan_bwres_requests_free(req);
293         if (ret != 0) return ret;
294
295         return 0;
296 }
297
298 /**
299  * frescan_bwres_negotiate()
300  */
301
302 int frescan_bwres_negotiate(frescan_network_t net,
303                             const frsh_contract_t *contract,
304                             frescan_ss_t *ss,
305                             bool *accepted)
306 {
307         int ret;
308         frsh_contracts_group_t contracts_to_neg;
309         frescan_ss_group_t ss_new;
310
311         contracts_to_neg.size = 1;
312         contracts_to_neg.contracts[0] = *contract;
313
314         ret = frescan_bwres_group_change_mode_sync
315                         (net, &contracts_to_neg, NULL, NULL,
316                          NULL, &ss_new, accepted);
317         if (ret != 0) return ret;
318
319         if (*accepted) {
320                 *ss = ss_new.ss[0];
321         }
322
323         return 0;
324 }
325
326 /**
327  * frescan_bwres_renegotiate()
328  */
329
330 int frescan_bwres_renegotiate(frescan_network_t net,
331                               const frsh_contract_t *contract,
332                               frescan_ss_t ss,
333                               bool *accepted)
334 {
335         frsh_contracts_group_t contracts_to_reneg;
336         frescan_ss_group_t ss_to_reneg;
337
338         contracts_to_reneg.size = 1;
339         contracts_to_reneg.contracts[0] = *contract;
340
341         ss_to_reneg.size = 1;
342         ss_to_reneg.ss[0] = ss;
343
344         return frescan_bwres_group_change_mode_sync
345                 (net, NULL, &contracts_to_reneg, &ss_to_reneg,
346                  NULL, NULL, accepted);
347 }
348
349 /**
350  * frescan_bwres_cancel()
351  */
352
353 int frescan_bwres_cancel(frescan_network_t net,
354                          frescan_ss_t      ss)
355 {
356         frescan_ss_group_t ss_to_cancel;
357
358         ss_to_cancel.size = 1;
359         ss_to_cancel.ss[0] = ss;
360
361         return frescan_bwres_group_change_mode_sync
362                         (net, NULL, NULL, NULL, &ss_to_cancel, NULL, NULL);
363 }