#include "frescan_bwres_mode_change.h"
#include "frescan_data.h"
+#include "frescan_servers.h"
+#include "frescan_bwres_messages.h"
#include <misc/linux_list.h>
+
+static int frescan_bwres_budget_change(frescan_request_data_t *req_data,
+ frescan_node_t node,
+ frescan_sa_mode_change_type_t mode_change_type);
+
/**
* frescan_bwres_mode_change_protocol() - performs the mode change
*
int frescan_bwres_mode_change_protocol(frescan_request_data_t *req_data)
{
- int ret;
+ int ret, i;
frescan_node_t node;
frescan_sa_vres_t *vres;
frsh_sa_vres_data_t *sa_vres_data;
frsh_sa_time_t max_period_in_budget_dec;
frsh_sa_time_t max_period_in_budget_inc;
- frescan_request_data_t tmp_req_data;
+ struct timespec start_timestamp, next_activation;
for(node=0; node<FRESCAN_MX_NODES; node++) {
INIT_LIST_HEAD(&the_networks[req_data->net].
vres->old_p = sa_vres_data->p;
}
- // mode change for B- members
- for(node=0; node<FRESCAN_MX_NODES; node++) { // TODO: end with master
- list_for_each_entry(vres,
- &the_networks[req_data->net].
- mode_change_budget_dec_list_head[node],
- mode_change_list)
- {
- if (node == FRESCAN_NEG_MASTER_NODE) {
- // put the values
- the_servers_pool[req_data->net][vres->ss].params = ...
+ // 1.- mode change for B- members
+ for(i=(FRESCAN_MX_NODES-1); i>=0; i--) {
+ ret = frescan_bwres_budget_change(req_data,
+ (frescan_node_t)i,
+ FRESCAN_SA_BUDGET_DEC);
+ if (ret != 0) return -1;
+ }
+
+ // 2.- wait the time needed to keep schedulability
+ ret = clock_gettime(CLOCK_MONOTONIC,
+ &start_timestamp);
+ if (ret != 0) return -1;
+
+ add_timespec(next_activation,
+ frsh_rel_time_to_timespec(frsh_sa_time_to_rel_time
+ (max_period_in_budget_inc)),
+ frsh_rel_time_to_timespec(frsh_sa_time_to_rel_time
+ (max_period_in_budget_dec)));
+ incr_timespec(next_activation, start_timestamp);
+ ret = clock_nanosleep(CLOCK_MONOTONIC,
+ TIMER_ABSTIME,
+ &next_activation,
+ NULL);
+ if (ret != 0) return -1;
+ // 3-. mode change for B+ members
+ for(i=(FRESCAN_MX_NODES-1); i>=0; i--) {
+ ret = frescan_bwres_budget_change(req_data,
+ (frescan_node_t)i,
+ FRESCAN_SA_BUDGET_INC);
+ if (ret != 0) return -1;
+ }
+
+ return 0;
+}
+static int frescan_bwres_budget_change
+ (frescan_request_data_t *req_data,
+ frescan_node_t node,
+ frescan_sa_mode_change_type_t mode_change_type)
+{
+ int ret;
+ frescan_server_params_t server_params;
+ frescan_sa_vres_t *vres;
+ frescan_request_data_t tmp_req_data;
+ struct timespec start_timestamp, next_activation;
+ struct list_head *the_mode_change_list;
+ if (mode_change_type == FRESCAN_SA_BUDGET_INC) {
+ the_mode_change_list = &the_networks[req_data->net].
+ mode_change_budget_inc_list_head[node];
+ } else {
+ the_mode_change_list = &the_networks[req_data->net].
+ mode_change_budget_dec_list_head[node];
+ }
+
+ list_for_each_entry(vres, the_mode_change_list, mode_change_list)
+ {
+ server_params.budget = frsh_rel_time_to_usec(
+ frsh_sa_time_to_rel_time(vres->old_c)) /
+ FRESCAN_FRAME_TX_TIME_US;
+ server_params.period = frsh_sa_time_to_rel_time(vres->old_t);
+ server_params.prio = vres->old_p;
+
+ if (node == FRESCAN_NEG_MASTER_NODE) {
+ if (mode_change_type == FRESCAN_SA_BUDGET_INC) {
+ // Local: Update server
+ ret = frescan_servers_update(req_data->net,
+ &server_params,
+ vres->ss);
+ if (ret != 0) return ret;
} else {
- if (req_data->request_node != FRESCAN_NEG_MASTER_NODE) {
- DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG,
- "sending reply\n");
- req_data->type = FRESCAN_REP_NEG;
- ret = frescan_messages_send_request(req_data);
- assert(ret == 0);
- } else {
- tmp_req_data.type = FRESCAN_REP_CHANGE;
- tmp_req_data.node = ...;
-
- ret = frescan_messages_send_request(&tmp_req_data);
- if (ret != 0) return -1;
- }
+ // Local: Change perceived allocation
+ ret = frescan_servers_set_perceived
+ (req_data->net,
+ &server_params,
+ vres->ss);
+ if (ret != 0) return ret;
}
- }
+ } else {
+ if ((node == req_data->request_node) &&
+ (vres->ss == req_data->ss)) {
+ // External: send reply to reneg
+ req_data->type = FRESCAN_REP_NEG;
+ req_data->final_values = server_params;
- if (node == FRESCAN_NEG_MASTER_NODE) {
- beginning = clock
- // delay
- clock_nanosleep(absolute, beginning+period
- // commmit
- list_del lo que ha disminuido
+ ret = frescan_messages_send_request(req_data);
+ if (ret != 0) return -1;
+ } else {
+ // External: send SC change update
+ tmp_req_data.net = req_data->net;
+ tmp_req_data.type = mode_change_type;
+ tmp_req_data.request_node = node;
+
+ ret = frescan_messages_send_request
+ (&tmp_req_data);
+ if (ret != 0) return -1;
+ }
}
}
- // wait the time needed to keep schedulability
+ if (mode_change_type == FRESCAN_SA_BUDGET_INC) return 0;
+ if (node == FRESCAN_NEG_MASTER_NODE) {
+ ret = clock_gettime(CLOCK_MONOTONIC, &start_timestamp);
+ if (ret != 0) return -1;
- // mode change for B+ members
+ list_for_each_entry
+ (vres, the_mode_change_list, mode_change_list)
+ {
+ add_timespec(next_activation,
+ start_timestamp,
+ frsh_rel_time_to_timespec
+ (frsh_sa_time_to_rel_time
+ (vres->old_t)));
+ ret = clock_nanosleep(CLOCK_MONOTONIC,
+ TIMER_ABSTIME,
+ &next_activation,
+ NULL);
+ if (ret != 0) return -1;
+
+ ret = frescan_servers_commit_perceived(req_data->net,
+ vres->ss);
+ if (ret != 0) return ret;
+ }
+ }
return 0;
}