]> rtime.felk.cvut.cz Git - frescor/fna.git/blobdiff - src_frescan/frescan_bwres.c
add debugging message
[frescor/fna.git] / src_frescan / frescan_bwres.c
index ac47359dba09dc176f4f5a74c850a8ca374251d8..f2b0035721708d47d251f55bafbb2f4d264c1cde 100644 (file)
  *
  * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
  *
+ * @license
+ *
+ * -----------------------------------------------------------------------
+ *  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+ *
+ *    Universidad de Cantabria,              SPAIN
+ *    University of York,                    UK
+ *    Scuola Superiore Sant'Anna,            ITALY
+ *    Kaiserslautern University,             GERMANY
+ *    Univ. Politécnica  Valencia,           SPAIN
+ *    Czech Technical University in Prague,  CZECH REPUBLIC
+ *    ENEA                                   SWEDEN
+ *    Thales Communication S.A.              FRANCE
+ *    Visual Tools S.A.                      SPAIN
+ *    Rapita Systems Ltd                     UK
+ *    Evidence                               ITALY
+ *
+ *    See http://www.frescor.org for a link to partners' websites
+ *
+ *           FRESCOR project (FP6/2005/IST/5-034026) is funded
+ *        in part by the European Union Sixth Framework Programme
+ *        The European Union is not liable of any use that may be
+ *        made of this code.
+ *
+ *  This file is part of FRESCAN
+ *
+ *  FRESCAN is free software; you can  redistribute it and/or  modify
+ *  it under the terms of  the GNU General Public License as published by
+ *  the Free Software Foundation;  either  version 2, or (at  your option)
+ *  any later version.
+ *
+ *  FRESCAN  is distributed  in  the hope  that  it  will  be useful,  but
+ *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
+ *  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
+ *  General Public License for more details.
+ *
+ *  You should have  received a  copy of  the  GNU  General Public License
+ *  distributed  with  FRESCAN;  see file COPYING.   If not,  write to the
+ *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
+ *  02111-1307, USA.
+ *
+ * As a special exception, including FRESCAN header files in a file,
+ * instantiating FRESCAN generics or templates, or linking other files
+ * with FRESCAN objects to produce an executable application, does not
+ * by itself cause the resulting executable application to be covered
+ * by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be
+ * covered by the GNU Public License.
+ * -----------------------------------------------------------------------
+ *
  */
 
+#include "frsh.h"
 #include "frescan_bwres.h"
 #include "frescan_bwres_requests.h"
+#include "frescan_bwres_robjs.h"
 #include "frescan_bwres_messages.h"
 #include "frescan_bwres_threads.h"
+#include "frescan_bwres_analysis.h"
 #include "frescan_data.h"
 #include "frescan_debug.h"
 #include "frescan_config.h"
 int frescan_bwres_init(frescan_network_t net)
 {
         int ret;
-        frescan_server_params_t params;
+        frescan_node_t node;
+        frescan_ss_t neg_msg_ss_id;
+        frescan_server_params_t server_params;
+        frescan_bwres_sa_init_params_t init_params;
+        frsh_contract_t neg_msgs_contract;
+        frsh_rel_time_t neg_msgs_budget;
+        frsh_rel_time_t neg_msgs_period;
+
+        init_params.min_prio = FRESCAN_BWRES_SS_MIN_PRIO;
+        init_params.max_prio = FRESCAN_BWRES_SS_MAX_PRIO;
+
+        if (frescan_data[net].local_node == FRESCAN_BWRES_MASTER_NODE) {
+            ret = frescan_bwres_sa_init(&frescan_data[net].scenario,
+                                        &init_params);
+            if (ret != 0) return ret;
+
+            // Add contracts for the negotiation messages
+            ret = frsh_contract_init(&neg_msgs_contract);
+            if (ret != 0) return ret;
+
+            neg_msgs_budget = frsh_usec_to_rel_time(
+                                        (long)FRESCAN_FRAME_TX_TIME_US *
+                                              FRESCAN_BWRES_NEG_MSG_BUDGET);
+
+            neg_msgs_period = frsh_usec_to_rel_time(
+                                        (long)FRESCAN_BWRES_NEG_MSG_PERIOD);
+
+            ret = frsh_contract_set_basic_params(&neg_msgs_contract,
+                                                 &neg_msgs_budget,
+                                                 &neg_msgs_period,
+                                                 FRSH_WT_INDETERMINATE,
+                                                 FRSH_CT_REGULAR);
+            if (ret != 0) return ret;
+
+            ret = frsh_contract_set_preemption_level
+                            (&neg_msgs_contract, FRESCAN_BWRES_NEG_MSG_PRIO);
+            if (ret != 0) return ret;
+
+            for(node=0; node<FRESCAN_MX_NODES; node++) {
+                    ret = freelist_init(&frescan_data[net].scenario.
+                                                        ss_id_freelist[node],
+                                                        FRESCAN_MX_IDS);
+                    if (ret != 0) return ret;
+
+                    ret = freelist_alloc(&frescan_data[net].scenario.
+                                                        ss_id_freelist[node]);
+                    if (ret < 0) return -1;
+
+                    neg_msg_ss_id = (frescan_ss_t)ret;
 
-        // TODO: server params must be configurable
-        // TODO: initialization tree like in DTM
-        params.values.budget = 5;
-        params.values.period.tv_sec = 1;
-        params.values.period.tv_nsec = 0;
-        params.prio = FRESCAN_BWRES_NEG_MESSAGES_PRIO;
+                    DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
+                          "manager contract node:%u b:(%d,%d) t:(%d,%d) p:%u\n",
+                          node,
+                          neg_msgs_budget.tv_sec, neg_msgs_budget.tv_nsec,
+                          neg_msgs_period.tv_sec, neg_msgs_period.tv_nsec,
+                          FRESCAN_BWRES_NEG_MSG_PRIO);
 
-        ret = frescan_servers_create(net, &params,
-                                     &the_networks[net].neg_messages_ss_id);
+                    ret = frescan_bwres_sa_add_contract
+                                    (&frescan_data[net].scenario,
+                                     neg_msg_ss_id,
+                                     node,
+                                     &neg_msgs_contract);
+                    if (ret != 0) return ret;
+            }
+        }
+
+        server_params.budget = FRESCAN_BWRES_NEG_MSG_BUDGET;
+        server_params.period = frsh_rel_time_to_timespec(
+                                        frsh_usec_to_rel_time(
+                                        (long)FRESCAN_BWRES_NEG_MSG_PERIOD));
+        server_params.prio   = FRESCAN_BWRES_NEG_MSG_PRIO;
+
+        ret = frescan_servers_create(net, &server_params,
+                                     &frescan_data[net].neg_messages_ss_id);
+        if (ret != 0) return ret;
+
+        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "neg_msg_ss_id: %u\n",
+              frescan_data[net].neg_messages_ss_id);
+
+        ret = frescan_bwres_robjs_init(FRESCAN_BWRES_ROBJS_MX_CEILING);
         if (ret != 0) return ret;
 
-        ret = frescan_bwres_robjs_init(FRESCAN_REPLY_OBJECTS_MX_CEILING);
+        ret = frescan_bwres_requests_init(FRESCAN_BWRES_REQ_MX_CEILING);
         if (ret != 0) return ret;
 
-        ret = frescan_requests_init(FRESCAN_REQUESTS_MX_CEILING);
+        ret = frescan_messages_init(net);
         if (ret != 0) return ret;
 
         ret = frescan_manager_thread_create(net);
@@ -61,44 +183,86 @@ int frescan_bwres_init(frescan_network_t net)
 }
 
 /**
- * frescan_bwres_negotiate()
- *
- * to negotiate a contract we follow the next steps:
+ * frescan_bwres_group_change_mode_sync()
  *
- * 1.- prepare a request
+ * 1.- allocate and prepare the GN request
  * 2.- enqueue the request
  * 3.- wait in the reply object for a reply
- * 4.- return the final values and free the request
- *
+ *     (unless there are only cancellations)
+ * 4.- free the request
  */
 
-int frescan_bwres_negotiate(frescan_network_t net,
-                            const frescan_contract_t *contract,
-                            frescan_ss_t *id)
+int frescan_bwres_group_change_mode_sync
+                (frescan_network_t            net,
+                 const frsh_contracts_group_t *contracts_to_neg,
+                 const frsh_contracts_group_t *contracts_to_reneg,
+                 const frescan_ss_group_t     *ss_to_reneg,
+                 const frescan_ss_group_t     *ss_to_cancel,
+                 frescan_ss_group_t           *ss_new,
+                 bool                         *accepted)
 {
         int ret;
-        frescan_request_id_t   req;
-        frescan_request_data_t *req_data;
+        frescan_bwres_request_id_t req;
+        frescan_bwres_request_data_t *req_data;
 
-        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a negotiation request\n");
+        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a GN request\n");
 
-        ret = frescan_requests_alloc(&req);
+        ret = frescan_bwres_requests_alloc(&req);
         if (ret != 0) return ret;
 
-        ret = frescan_requests_get_data(req, &req_data);
+        ret = frescan_bwres_requests_get_data(req, &req_data);
         if (ret != 0) return ret;
 
-        req_data->type         = FRESCAN_REQ_NEG;
+        req_data->net          = net;
+        req_data->type         = FRESCAN_BWRES_REQ_GN;
         req_data->req          = req;
-        req_data->contract     = (frescan_contract_t *)contract;
-        req_data->request_node = the_networks[net].local_node;
+        req_data->request_node = frescan_data[net].local_node;
+
+        if (contracts_to_neg == NULL) {
+                req_data->contracts_to_neg = &req_data->contracts_to_neg_data;
+                req_data->contracts_to_neg->size = 0;
+        } else {
+                req_data->contracts_to_neg =
+                                (frsh_contracts_group_t *)contracts_to_neg;
+        }
+
+        if (contracts_to_reneg == NULL) {
+                req_data->contracts_to_reneg = &req_data->
+                                                       contracts_to_reneg_data;
+                req_data->contracts_to_reneg->size = 0;
+        } else {
+                req_data->contracts_to_reneg = (frsh_contracts_group_t *)
+                                contracts_to_reneg;
+        }
+
+        if (ss_to_reneg == NULL) {
+                req_data->ss_to_reneg = &req_data->ss_to_reneg_data;
+                req_data->ss_to_reneg->size = 0;
+        } else {
+                req_data->ss_to_reneg = (frescan_ss_group_t *)ss_to_reneg;
+        }
+
+        if (ss_to_cancel == NULL) {
+                req_data->ss_to_cancel = &req_data->ss_to_cancel_data;
+                req_data->ss_to_cancel->size = 0;
+        } else {
+                req_data->ss_to_cancel = (frescan_ss_group_t *)ss_to_cancel;
+
+        }
+
+        if (ss_new == NULL) {
+                req_data->ss_new = &req_data->ss_new_data;
+                req_data->ss_new->size = 0;
+        } else {
+                req_data->ss_new = ss_new;
+        }
 
         ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
         if (ret != 0) return ret;
 
         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue the negotiation request\n");
 
-        ret = frescan_requests_enqueue(req);
+        ret = frescan_bwres_requests_enqueue(req);
         if (ret != 0) return ret;
 
         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
@@ -110,30 +274,90 @@ int frescan_bwres_negotiate(frescan_network_t net,
         if (ret != 0) return ret;
 
         switch (req_data->return_value) {
-                case FRESCAN_REQ_ACCEPTED:
+                case FRESCAN_BWRES_REQ_ACCEPTED:
                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n");
-                        *id = req_data->ss;
-                        ret = 0;
+                        *accepted = true;
                         break;
 
-                case FRESCAN_REQ_NOT_ACCEPTED:
+                case FRESCAN_BWRES_REQ_NOT_ACCEPTED:
                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation FAIL\n");
-                        ret = -1;
-                        break;
-
-                case FRESCAN_REQ_ERROR:
-                        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation ERROR\n");
-                        ret = -1;
+                        *accepted = false;
                         break;
 
                 default:
-                        ERROR("return_value unknown\n");
+                        FRESCAN_ERROR("return_value unknown\n");
                         return -1;
         }
 
-        DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "free the request\n");
+        ret = frescan_bwres_requests_free(req);
+        if (ret != 0) return ret;
+
+        return 0;
+}
+
+/**
+ * frescan_bwres_negotiate()
+ */
+
+int frescan_bwres_negotiate(frescan_network_t net,
+                            const frsh_contract_t *contract,
+                            frescan_ss_t *ss,
+                            bool *accepted)
+{
+        int ret;
+        frsh_contracts_group_t contracts_to_neg;
+        frescan_ss_group_t ss_new;
+
+        contracts_to_neg.size = 1;
+        contracts_to_neg.contracts[0] = *contract;
+
+        ret = frescan_bwres_group_change_mode_sync
+                        (net, &contracts_to_neg, NULL, NULL,
+                         NULL, &ss_new, accepted);
+        if (ret != 0) return ret;
+
+        if (*accepted) {
+                *ss = ss_new.ss[0];
+        }
+
+        return 0;
+}
+
+/**
+ * frescan_bwres_renegotiate()
+ */
+
+int frescan_bwres_renegotiate(frescan_network_t net,
+                              const frsh_contract_t *contract,
+                              frescan_ss_t ss,
+                              bool *accepted)
+{
+        frsh_contracts_group_t contracts_to_reneg;
+        frescan_ss_group_t ss_to_reneg;
+
+        contracts_to_reneg.size = 1;
+        contracts_to_reneg.contracts[0] = *contract;
+
+        ss_to_reneg.size = 1;
+        ss_to_reneg.ss[0] = ss;
+
+        return frescan_bwres_group_change_mode_sync
+                (net, NULL, &contracts_to_reneg, &ss_to_reneg,
+                 NULL, NULL, accepted);
+}
+
+/**
+ * frescan_bwres_cancel()
+ */
+
+int frescan_bwres_cancel(frescan_network_t net,
+                         frescan_ss_t      ss)
+{
+        frescan_ss_group_t ss_to_cancel;
 
-        frescan_requests_free(req);
+        ss_to_cancel.size = 1;
+        ss_to_cancel.ss[0] = ss;
 
-        return ret;
+        return frescan_bwres_group_change_mode_sync
+                        (net, NULL, NULL, NULL, &ss_to_cancel, NULL, NULL);
 }