From e1cc80051455d1a561c136c8b04abc86c3d67d9a Mon Sep 17 00:00:00 2001 From: sangorrin Date: Sun, 20 Jul 2008 12:09:12 +0000 Subject: [PATCH] changes to use the FRSH FSA module to do the analysis and spare capacity. TODO: finish the mode change protocol and test it all... for now frescan compilation is broken, until i finish it git-svn-id: http://www.frescor.org/private/svn/frescor/fna/trunk@1306 35b4ef3e-fd22-0410-ab77-dab3279adceb --- src_frescan/frescan.c | 64 ++-- src_frescan/frescan_bwres.c | 31 +- src_frescan/frescan_bwres.h | 4 +- src_frescan/frescan_bwres_analysis.c | 309 ++++++------------- src_frescan/frescan_bwres_analysis.h | 120 ++----- src_frescan/frescan_bwres_fna.c | 61 ++-- src_frescan/frescan_bwres_frsh_fna.c | 10 +- src_frescan/frescan_bwres_messages.c | 157 ++++++++-- src_frescan/frescan_bwres_mode_change.c | 201 ++++++++++++ src_frescan/frescan_bwres_mode_change.h | 83 +++++ src_frescan/frescan_bwres_requests.h | 9 +- src_frescan/frescan_bwres_robjs.c | 2 +- src_frescan/frescan_bwres_threads.c | 135 +++++--- src_frescan/frescan_data.h | 85 ++--- src_frescan/frescan_debug.h | 4 +- src_frescan/frescan_hw_buffer.c | 8 +- src_frescan/frescan_packets.c | 2 +- src_frescan/frescan_queues.c | 18 +- src_frescan/frescan_servers.c | 22 +- src_frescan/frescan_servers.h | 1 - src_frescan/frescan_servers_replenishments.c | 25 +- 21 files changed, 806 insertions(+), 545 deletions(-) create mode 100644 src_frescan/frescan_bwres_mode_change.c create mode 100644 src_frescan/frescan_bwres_mode_change.h diff --git a/src_frescan/frescan.c b/src_frescan/frescan.c index 56531ae..3c6fc8b 100644 --- a/src_frescan/frescan.c +++ b/src_frescan/frescan.c @@ -119,7 +119,7 @@ int frescan_init(frescan_init_params_t *params) fd = open (can_path, O_RDWR); if (fd == -1) { - ERROR ("could not open /dev/can%u\n", params->net); + FRESCAN_ERROR ("could not open /dev/can%u\n", params->net); return -1; } @@ -141,7 +141,7 @@ int frescan_init(frescan_init_params_t *params) ret = ioctl(fd, CAN_IOCTL_SET_FILTERS, &ioctl_filters); if (ret == -1) { - ERROR ("ioctl CAN_IOCTL_SET_FILTERS failed /dev/can%u\n", + FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_FILTERS failed /dev/can%u\n", params->net); return -1; } @@ -150,21 +150,21 @@ int frescan_init(frescan_init_params_t *params) ret = ioctl(fd, CAN_IOCTL_SET_TX_HOOK, frescan_hook_frame_sent); if (ret == -1) { - ERROR ("ioctl CAN_IOCTL_SET_TX_HOOK failed /dev/can%u\n", + FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_TX_HOOK failed /dev/can%u\n", params->net); return -1; } ret = ioctl(fd, CAN_IOCTL_SET_RX_HOOK, frescan_hook_frame_recv); if (ret == -1) { - ERROR ("ioctl CAN_IOCTL_SET_RX_HOOK failed /dev/can%u\n", + FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_RX_HOOK failed /dev/can%u\n", params->net); return -1; } ret = ioctl(fd, CAN_IOCTL_SET_AB_HOOK, frescan_hook_frame_aborted); if (ret == -1) { - ERROR ("ioctl CAN_IOCTL_SET_AB_HOOK failed /dev/can%u\n", + FRESCAN_ERROR ("ioctl CAN_IOCTL_SET_AB_HOOK failed /dev/can%u\n", params->net); return -1; } @@ -173,25 +173,25 @@ int frescan_init(frescan_init_params_t *params) ret = frescan_data_init(fd, params); if (ret != 0) { - ERROR("could not initialize the global data\n"); + FRESCAN_ERROR("could not initialize the global data\n"); return -1; } ret = frescan_packets_init(); if (ret != 0) { - ERROR("could not initialize the packets pool\n"); + FRESCAN_ERROR("could not initialize the packets pool\n"); return -1; } ret = frescan_queues_init(&the_networks[params->net].queues, params); if (ret != 0) { - ERROR("could not initialize the queues\n"); + FRESCAN_ERROR("could not initialize the queues\n"); return -1; } ret = frescan_servers_init(params->net); if (ret != 0) { - ERROR("could not initialize the servers\n"); + FRESCAN_ERROR("could not initialize the servers\n"); return -1; } @@ -221,7 +221,7 @@ int frescan_send(const frescan_send_params_t *params, "checking arguments (msg size=%d)\n", size); if ((params == NULL) || (msg == NULL) || (size == 0)) { - ERROR("arguments are not ok\n"); + FRESCAN_ERROR("arguments are not ok\n"); return -1; } @@ -232,7 +232,7 @@ int frescan_send(const frescan_send_params_t *params, FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock); if (packet == NULL) { - ERROR("could not allocate packet\n"); + FRESCAN_ERROR("could not allocate packet\n"); return -1; } packet->flags = params->flags; // set the flags (to remember them) @@ -244,7 +244,7 @@ int frescan_send(const frescan_send_params_t *params, FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock); if (packet->frame == NULL) { - ERROR("could not allocate frame\n"); + FRESCAN_ERROR("could not allocate frame\n"); return -1; } @@ -305,7 +305,7 @@ int frescan_send(const frescan_send_params_t *params, FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock); if (ret != 0) { - ERROR("could not enqueue the packet\n"); + FRESCAN_ERROR("could not enqueue the packet\n"); return -1; } } else { @@ -314,7 +314,7 @@ int frescan_send(const frescan_send_params_t *params, FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock); if (ret != 0) { - ERROR("could not enqueue the packet\n"); + FRESCAN_ERROR("could not enqueue the packet\n"); return -1; } } @@ -324,7 +324,7 @@ int frescan_send(const frescan_send_params_t *params, FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock); if (ret != 0) { - ERROR("could not update hw buffer\n"); + FRESCAN_ERROR("could not update hw buffer\n"); return -1; } @@ -372,7 +372,7 @@ int frescan_recv(const frescan_recv_params_t *params, ret = frescan_pqueue_dequeue(pqueue, &head, prio, blocking); if (ret != 0) { - ERROR ("could not dequeue packet\n"); + FRESCAN_ERROR ("could not dequeue packet\n"); return -1; } @@ -383,7 +383,7 @@ int frescan_recv(const frescan_recv_params_t *params, *recv_bytes = 0; return 0; } else { - ERROR ("blocking true, and packet = null\n"); + FRESCAN_ERROR ("blocking true, and packet = null\n"); return -1; } } @@ -410,13 +410,13 @@ int frescan_recv(const frescan_recv_params_t *params, ret = can_framespool_free(packet->frame); if (ret != 0) { - ERROR("could not free frame\n"); + FRESCAN_ERROR("could not free frame\n"); return -1; } ret = frescan_packets_free(packet); if (ret != 0) { - ERROR("could not free packet\n"); + FRESCAN_ERROR("could not free packet\n"); return -1; } } @@ -426,7 +426,7 @@ int frescan_recv(const frescan_recv_params_t *params, FRESCAN_RELEASE_LOCK(&the_networks[params->net].lock); if (ret != 0) { - ERROR("could not free head packet\n"); + FRESCAN_ERROR("could not free head packet\n"); return -1; } @@ -519,7 +519,7 @@ static int frescan_hook_frame_recv (const struct can_chip_t *chip, pqueue = the_networks[net].queues.rx_channel_queues[channel]; ret = frescan_pqueue_enqueue(pqueue, head, prio); if (ret != 0) { - ERROR("could not enqueue message in channel queue\n"); + FRESCAN_ERROR("could not enqueue message in channel queue\n"); return -1; } @@ -572,7 +572,7 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip) ret = frescan_servers_frame_sent(chip->minor, id, packet); if (ret != 0) { - ERROR("could not let the server a frame was sent\n"); + FRESCAN_ERROR("could not let the server a frame was sent\n"); return -1; } } @@ -592,7 +592,7 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip) pqueue = the_networks[chip->minor].queues.tx_fp_queue; ret = frescan_pqueue_requeue(pqueue, packet, prio); if (ret != 0) { - ERROR("could not requeue the packet\n"); + FRESCAN_ERROR("could not requeue the packet\n"); return -1; } } else if (packet->flags & FRESCAN_SS) { @@ -600,11 +600,11 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip) "requeue server %u packet\n", id); ret = frescan_servers_requeue(chip->minor, id, packet); if (ret != 0) { - ERROR("could not requeue the packet\n"); + FRESCAN_ERROR("could not requeue the packet\n"); return -1; } } else { - ERROR("flags are not correct\n"); + FRESCAN_ERROR("flags are not correct\n"); return -1; } } else { @@ -613,13 +613,13 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip) ret = can_framespool_free(packet->frame); if (ret != 0) { - ERROR ("could not free the frame\n"); + FRESCAN_ERROR ("could not free the frame\n"); return ret; } ret = frescan_packets_free(packet); if (ret != 0) { - ERROR ("could not free the packet\n"); + FRESCAN_ERROR ("could not free the packet\n"); return ret; } @@ -630,7 +630,7 @@ static int frescan_hook_frame_sent(const struct can_chip_t *chip) ret = frescan_hw_buffer_update(chip->minor); if (ret != 0) { - ERROR("could not update hw buffer\n"); + FRESCAN_ERROR("could not update hw buffer\n"); return -1; } @@ -672,7 +672,7 @@ static int frescan_hook_frame_aborted(const struct can_chip_t *chip) pqueue = the_networks[chip->minor].queues.tx_fp_queue; ret = frescan_pqueue_requeue(pqueue, packet, prio); if (ret != 0) { - ERROR("could not requeue the packet\n"); + FRESCAN_ERROR("could not requeue the packet\n"); return -1; } } else if (packet->flags & FRESCAN_SS) { @@ -681,11 +681,11 @@ static int frescan_hook_frame_aborted(const struct can_chip_t *chip) ret = frescan_servers_requeue(chip->minor, id, packet); if (ret != 0) { - ERROR("could not requeue the packet\n"); + FRESCAN_ERROR("could not requeue the packet\n"); return -1; } } else { - ERROR("flags are not correct\n"); + FRESCAN_ERROR("flags are not correct\n"); return -1; } @@ -693,7 +693,7 @@ static int frescan_hook_frame_aborted(const struct can_chip_t *chip) ret = frescan_hw_buffer_update(chip->minor); if (ret != 0) { - ERROR("could not update hw buffer\n"); + FRESCAN_ERROR("could not update hw buffer\n"); return -1; } diff --git a/src_frescan/frescan_bwres.c b/src_frescan/frescan_bwres.c index 9bee1ba..ebffa1a 100644 --- a/src_frescan/frescan_bwres.c +++ b/src_frescan/frescan_bwres.c @@ -93,9 +93,9 @@ int frescan_bwres_init(frescan_network_t net) &sa_init_params); if (ret != 0) return ret; - server_params.values.budget = 5; - server_params.values.period.tv_sec = 1; - server_params.values.period.tv_nsec = 0; + server_params.budget = 5; + server_params.period.tv_sec = 1; + server_params.period.tv_nsec = 0; server_params.prio = FRESCAN_BWRES_NEG_MESSAGES_PRIO; ret = frescan_servers_create(net, &server_params, @@ -134,7 +134,7 @@ int frescan_bwres_init(frescan_network_t net) */ int frescan_bwres_negotiate(frescan_network_t net, - const frescan_contract_t *contract, + const frsh_contract_t *contract, frescan_ss_t *ss, bool *accepted) { @@ -153,7 +153,7 @@ int frescan_bwres_negotiate(frescan_network_t net, req_data->type = FRESCAN_REQ_NEG; req_data->req = req; - req_data->contract = (frescan_contract_t *)contract; + req_data->contract = (frsh_contract_t *)contract; req_data->request_node = the_networks[net].local_node; req_data->net = net; @@ -161,9 +161,10 @@ int frescan_bwres_negotiate(frescan_network_t net, if (ret != 0) return ret; // NOTE: we preallocate a server for the negotiation process - server_params.values.budget = contract->min_values.budget; - server_params.values.period = contract->min_values.period; - server_params.prio = contract->prio; + server_params.budget = 0; + server_params.period.tv_sec = 0; + server_params.period.tv_nsec = 0; + server_params.prio = 0; ret = frescan_servers_create(net, &server_params, &req_data->ss); if (ret != 0) return ret; @@ -186,7 +187,7 @@ int frescan_bwres_negotiate(frescan_network_t net, DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n"); *accepted = true; *ss = req_data->ss; - server_params.prio = req_data->final_values.server_prio; + server_params = req_data->final_values; ret = frescan_servers_update(net, &server_params, *ss); if (ret != 0) return ret; break; @@ -199,7 +200,7 @@ int frescan_bwres_negotiate(frescan_network_t net, break; default: - ERROR("return_value unknown\n"); + FRESCAN_ERROR("return_value unknown\n"); return -1; } @@ -212,7 +213,7 @@ int frescan_bwres_negotiate(frescan_network_t net, */ int frescan_bwres_renegotiate(frescan_network_t net, - const frescan_contract_t *contract, + const frsh_contract_t *contract, frescan_ss_t ss, bool *accepted) { @@ -231,7 +232,7 @@ int frescan_bwres_renegotiate(frescan_network_t net, req_data->type = FRESCAN_REQ_RENEG; req_data->req = req; - req_data->contract = (frescan_contract_t *)contract; + req_data->contract = (frsh_contract_t *)contract; req_data->request_node = the_networks[net].local_node; req_data->net = net; req_data->ss = ss; @@ -256,9 +257,7 @@ int frescan_bwres_renegotiate(frescan_network_t net, case FRESCAN_REQ_ACCEPTED: DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "renegotiation OK\n"); *accepted = true; - server_params.values.budget = contract->min_values.budget; - server_params.values.period = contract->min_values.period; - server_params.prio = req_data->final_values.server_prio; + server_params = req_data->final_values; ret = frescan_servers_update(net, &server_params, ss); if (ret != 0) return ret; break; @@ -270,7 +269,7 @@ int frescan_bwres_renegotiate(frescan_network_t net, break; default: - ERROR("return_value unknown\n"); + FRESCAN_ERROR("return_value unknown\n"); return -1; } diff --git a/src_frescan/frescan_bwres.h b/src_frescan/frescan_bwres.h index f308d42..dc87d4d 100644 --- a/src_frescan/frescan_bwres.h +++ b/src_frescan/frescan_bwres.h @@ -73,12 +73,12 @@ extern int frescan_bwres_init(frescan_network_t net); extern int frescan_bwres_negotiate(frescan_network_t net, - const frescan_contract_t *contract, + const frsh_contract_t *contract, frescan_ss_t *ss, bool *accepted); extern int frescan_bwres_renegotiate(frescan_network_t net, - const frescan_contract_t *contract, + const frsh_contract_t *contract, frescan_ss_t ss, bool *accepted); diff --git a/src_frescan/frescan_bwres_analysis.c b/src_frescan/frescan_bwres_analysis.c index c8d8655..e55b835 100644 --- a/src_frescan/frescan_bwres_analysis.c +++ b/src_frescan/frescan_bwres_analysis.c @@ -3,72 +3,21 @@ * * @brief FRESCAN bandwith reservation layer: sched analysis * - * This module contains the scheduling analysis data and functions for the - * admission tests and spare capacity distribution of the negotiation layer. - * It provides an easy API easy to understand and in the implementation part - * it makes call to the general sched analysis module of FRSH which is shared - * with the CPU contracts layer in FRSH. + * @version 0.02 * - * EXAMPLE of utilization: + * @date 3-Jul-2008 * - * INITIALIZATION - * -------------- - * params.min_prio = 0; - * params.max_prio = 16; - * params.overhead = ...; - * frescan_sa_init(&scenario, ¶ms); - * - * NEGOTIATE - * --------- - * fadt_freelist_alloc(&freelist_contracts, &id); - * frescan_sa_add_contract(&scenario, &contracts[id], id); - * frescan_sa_sched_test(&scenario, &success); - * - * if (!success) { - * frescan_sa_remove_contract(&scenario, id); - * } else { - * frescan_sa_spare_capacity(&scenario); - * vres_id = to_vres(resource_type, resource_id, id); - * create vres runtime structures; - * - * for vres_id in active_vres_id { - * frescan_sa_get_final_values(&scenario, - * to_index(vres_id), - * &final_values); - * update vres runtime structures if necessary; - * } - * } - * - * RENEGOTIATE - * ----------- - * copy old_contract - * frescan_sa_update_contract(&scenario, to_index(vres_id), &contract); - * frescan_sa_sched_test(&scenario, &success); - * - * if (!success) { - * frescan_sa_update_contract(&sa_data, - * to_index(vres_id), - * &old_contract); - * } else { - * frescan_sa_spare_capacity(&scenario); - * for vres_id in active_vres_id { - * frescan_sa_get_final_values(&scenario, - * to_index(vres_id), - * &final_values); - * update vres runtime structures if necessary; - * } - * } - * - * CANCEL - * ------ - * frescan_sa_remove_contract(&scenario, to_index(vres_id)); - * frescan_sa_spare_capacity(&scenario); + * @author Daniel Sangorrin * - * @version 0.01 + * @comments * - * @date 15-Apr-2008 + * This module contains the scheduling analysis functions for the + * admission tests and spare capacity distribution of the bandwith + * reservation (bwres) layer. * - * @author Daniel Sangorrin + * The module "frescan_bwres_mode_change" must be used to apply finally this + * new parameters to the sporadic servers following an appropriate mode + * change protocol. * * @license * @@ -124,115 +73,124 @@ #include #include +#include +#include #include "frescan_bwres_analysis.h" -#undef ERROR #include "frescan_debug.h" /** * frescan_sa_init() - init the scenario * - * @scenario: the scenario (in out) - * @params: init params (in) + * Initialize the vres list and copy the initialization parameters */ int frescan_sa_init(frescan_sa_scenario_t *scenario, const frescan_sa_init_params_t *params) { -// int ret; -// -// ret = frsh_sa_scenario_init(scenario, params); -// return ret; + int ret; + frsh_sa_scenario_init_data_t fsa_scenario_init_data; - INIT_LIST_HEAD(&scenario->contracts_head.list); + INIT_LIST_HEAD(&scenario->vres_head.list); scenario->init_params = *params; + + ret = freelist_init(&scenario->fsa_id_freelist, + FRESCAN_MX_NODES*FRESCAN_MX_IDS); + if (ret != 0) return ret; + + fsa_scenario_init_data.min_priority = 1; + fsa_scenario_init_data.max_priority = 15; + fsa_scenario_init_data.ovhd_data.np = + frsh_rel_time_to_sa_time(frsh_usec_to_rel_time(0)); + + ret = frsh_sa_scenario_init(&scenario->fsa_scenario, + &fsa_scenario_init_data); + if (ret != 0) return -1; + return 0; } /** * frescan_sa_add_contract() - add a contract to the scenario * - * @scenario: the scenario (in out) - * @contract: the new contract (in) - * @ss: the preallocated ss identificator (in) - * @node: the node this contract belongs to (in) + * create the corresponding vres structure and set its values, and add the + * vres to the vres list */ -int frescan_sa_add_contract(frescan_sa_scenario_t *scenario, - const frescan_contract_t *contract, - frescan_ss_t ss, - frescan_node_t node) +int frescan_sa_add_contract(frescan_sa_scenario_t *scenario, + frescan_ss_t ss, + frescan_node_t node, + const frsh_contract_t *contract) { -// int ret; -// -// ret = frsh_sa_scenario_add_vres(scenario, contract, id); -// return ret; - frescan_sa_contract_t *sa_contract; + int ret; + frescan_sa_vres_t *sa_vres = &scenario->vres_pool[node][ss]; - sa_contract = &scenario->contracts[node][ss]; + sa_vres->contract = *contract; + sa_vres->node = node; + sa_vres->ss = ss; - sa_contract->contract = *contract; - sa_contract->node = node; - sa_contract->ss = ss; + ret = freelist_alloc(&scenario->fsa_id_freelist); + if (ret < 0) return -1; - list_add_tail(&sa_contract->list, - &scenario->contracts_head.list); + sa_vres->fsa_vres_global_id = (frsh_sa_vres_id_t)ret; + + list_add_tail(&sa_vres->list, + &scenario->vres_head.list); + + ret = frsh_sa_scenario_add_vres(&scenario->fsa_scenario, + &sa_vres->contract, + sa_vres->fsa_vres_global_id); + if (ret != 0) return -1; return 0; } /** * frescan_sa_update_contract() - update a contract in the scenario - * - * @scenario: the scenario (in out) - * @ss: the ss identificator (in) - * @node: the node this contract belongs to (in) - * @contract: the values to update the contract (in) - * @old_contract: the values of the previous contract. Can be NULL (out) */ -int frescan_sa_update_contract(frescan_sa_scenario_t *scenario, - frescan_ss_t ss, - frescan_node_t node, - const frescan_contract_t *contract, - frescan_contract_t *old_contract) +int frescan_sa_update_contract(frescan_sa_scenario_t *scenario, + frescan_ss_t ss, + frescan_node_t node, + const frsh_contract_t *contract, + frsh_contract_t *old_contract) { -// int ret; -// -// ret = frsh_sa_scenario_modify_vres(scenario, id, *contract); -// return ret; - frescan_sa_contract_t *sa_contract; - - sa_contract = &scenario->contracts[node][ss]; + int ret; + frescan_sa_vres_t *sa_vres = &scenario->vres_pool[node][ss]; if (old_contract != NULL) { - *old_contract = sa_contract->contract; + *old_contract = sa_vres->contract; } - sa_contract->contract = *contract; + sa_vres->contract = *contract; + + ret = frsh_sa_scenario_modify_vres(&scenario->fsa_scenario, + sa_vres->fsa_vres_global_id, + &sa_vres->contract); + if (ret != 0) return -1; return 0; } /** * frescan_sa_remove_contract() - remove a contract from the scenario - * - * @scenario: the scenario (in out) - * @ss: the ss to remove (in) - * @node: the node this contract belongs to (in) */ int frescan_sa_remove_contract(frescan_sa_scenario_t *scenario, frescan_ss_t ss, frescan_node_t node) { -// int ret; -// -// ret = frsh_sa_scenario_del_vres(scenario, id); -// return ret; - frescan_sa_contract_t *sa_contract; + int ret; + frescan_sa_vres_t *sa_vres = &scenario->vres_pool[node][ss]; + + ret = frsh_sa_scenario_del_vres(&scenario->fsa_scenario, + sa_vres->fsa_vres_global_id); + if (ret != 0) return -1; + + ret = freelist_free(&scenario->fsa_id_freelist, + sa_vres->fsa_vres_global_id); + if (ret < 0) return -1; - sa_contract = &scenario->contracts[node][ss]; - list_del(&sa_contract->list); + list_del(&sa_vres->list); return 0; } @@ -240,124 +198,35 @@ int frescan_sa_remove_contract(frescan_sa_scenario_t *scenario, /** * frescan_sa_sched_test() - perform a scheduling test on the scenario * - * @scenario: the scenario (in out) - * @success: if the scenario is schedulable or not (out) */ int frescan_sa_sched_test(frescan_sa_scenario_t *scenario, - bool *success) + bool *is_schedulable) { -// int ret; -// -// ret = frsh_sa_scenario_reset_to_min(scenario, NULL, NULL); -// if (ret != 0) goto error; -// -// ret = frsh_sa_assign_priorities(scenario, NULL, NULL, NULL, NULL); -// if (ret != 0) goto error; -// -// ret = frsh_sa_ceilings_ok(scenario); -// if (ret != 0) goto error; -// -// ret = frsh_sa_calculate_blockings(scenario); -// if (ret != 0) goto error; -// -// ret = frsh_sa_sched_test(scenario, success); -// if (ret != 0) goto error; -// -// return 0; -// -// error: -// *success = false; -// return ret; - - struct list_head *pos; - frescan_sa_contract_t *sa_contract; - int num_contracts; - double utilization, max_utilization, budget, period; - - // WARNING("simplified ub test (no blocks, prio ordered)\n"); - - utilization = 0.0; - num_contracts = 0; - - list_for_each(pos, &scenario->contracts_head.list) { - sa_contract = list_entry(pos, frescan_sa_contract_t, list); - sa_contract->final_values.server_prio = sa_contract->contract.prio; - - budget = (double)sa_contract->contract.min_values.budget * - (double)FRESCAN_FRAME_TX_TIME_US; - - period = timespec_to_double - (&sa_contract->contract.min_values.period); - - utilization = utilization + (budget / period); - - num_contracts++; - - DEBUG(FRESCAN_SA_ENABLE_DEBUG, - "sa_contract, node:%d ss:%d, c:%d t:(%d,%d) p:%d\n", - sa_contract->node, sa_contract->ss, - sa_contract->contract.min_values.budget, - sa_contract->contract.min_values.period.tv_sec, - sa_contract->contract.min_values.period.tv_nsec, - sa_contract->contract.prio); - } + int ret; - max_utilization = num_contracts * - (pow(2.0, 1.0/(double)num_contracts) - 1); + ret = frsh_sa_init_analysis(&scenario->fsa_scenario); + if (ret != 0) return -1; - DEBUG(FRESCAN_SA_ENABLE_DEBUG, "u:%f n:%d u_max:%f %s\n", - utilization, num_contracts, max_utilization, - (utilization < max_utilization) ? "accepted" : "not accepted"); + ret = frsh_sa_assign_priorities(&scenario->fsa_scenario); + if (ret != 0) return -1; - if (utilization < max_utilization) { - *success = true; - } else { - *success = false; - } + ret = frsh_sa_sched_test(&scenario->fsa_scenario, is_schedulable); + if (ret != 0) return -1; return 0; } /** - * frescan_sa_spare_capacity() - distribute the remaining spare capacity - * - * @scenario: the scenario (in out) + * frescan_sa_spare_capacity() - distribute the spare capacity */ int frescan_sa_spare_capacity(frescan_sa_scenario_t *scenario) { -// int ret; -// -// ret = frsh_sa_distribute_spare(scenario, -// NULL, NULL, NULL, NULL, NULL, NULL); -// return ret; - WARNING("not implemented, returning 0\n"); - return 0; -} - -/** - * frescan_sa_get_final_values() - get the final values - * - * @scenario: the scenario (in) - * @ss: the ss from which we want the final values (in) - * @node: the node this contract belongs to (in) - * @final_values: the final values (out) - */ - - -int frescan_sa_get_final_values(const frescan_sa_scenario_t *scenario, - frescan_ss_t ss, - frescan_node_t node, - frescan_sa_final_values_t *final_values) -{ -// final_values->budget = scenario->sa_vres_alloc[id].c; -// final_values->period = scenario->sa_vres_alloc[id].t; -// final_values->deadline = scenario->sa_vres_alloc[id].d; -// final_values->priority = scenario->sa_vres_alloc[id].p; -// return 0; + int ret; - *final_values = scenario->contracts[node][ss].final_values; + ret = frsh_sa_distribute_spare(&scenario->fsa_scenario); + if (ret != 0) return -1; return 0; } diff --git a/src_frescan/frescan_bwres_analysis.h b/src_frescan/frescan_bwres_analysis.h index 0d4c4cb..e932601 100644 --- a/src_frescan/frescan_bwres_analysis.h +++ b/src_frescan/frescan_bwres_analysis.h @@ -3,73 +3,22 @@ * * @brief FRESCAN bandwith reservation layer: sched analysis * - * This module contains the scheduling analysis data and functions for the - * admission tests and spare capacity distribution of the negotiation layer. - * It provides an easy API easy to understand and in the implementation part - * it makes call to the general sched analysis module of FRSH which is shared - * with the CPU contracts layer in FRSH. - * - * EXAMPLE of utilization: - * - * INITIALIZATION - * -------------- - * params.min_prio = 0; - * params.max_prio = 16; - * params.overhead = ...; - * frescan_sa_init(&scenario, ¶ms); - * - * NEGOTIATE - * --------- - * fadt_freelist_alloc(&freelist_contracts, &id); - * frescan_sa_add_contract(&scenario, &contracts[id], id); - * frescan_sa_sched_test(&scenario, &success); - * - * if (!success) { - * frescan_sa_remove_contract(&scenario, id); - * } else { - * frescan_sa_spare_capacity(&scenario); - * vres_id = to_vres(resource_type, resource_id, id); - * create vres runtime structures; - * - * for vres_id in active_vres_id { - * frescan_sa_get_final_values(&scenario, - * to_index(vres_id), - * &final_values); - * update vres runtime structures if necessary; - * } - * } - * - * RENEGOTIATE - * ----------- - * copy old_contract - * frescan_sa_update_contract(&scenario, to_index(vres_id), &contract); - * frescan_sa_sched_test(&scenario, &success); - * - * if (!success) { - * frescan_sa_update_contract(&sa_data, - * to_index(vres_id), - * &old_contract); - * } else { - * frescan_sa_spare_capacity(&scenario); - * for vres_id in active_vres_id { - * frescan_sa_get_final_values(&scenario, - * to_index(vres_id), - * &final_values); - * update vres runtime structures if necessary; - * } - * } - * - * CANCEL - * ------ - * frescan_sa_remove_contract(&scenario, to_index(vres_id)); - * frescan_sa_spare_capacity(&scenario); - * - * @version 0.01 - * - * @date 15-Apr-2008 + * @version 0.02 + * + * @date 3-Jul-2008 * * @author Daniel Sangorrin * + * @comments + * + * This module contains the scheduling analysis functions for the + * admission tests and spare capacity distribution of the bandwith + * reservation (bwres) layer. + * + * The module "frescan_bwres_mode_change" must be used to apply finally this + * new parameters to the sporadic servers following an appropriate mode + * change protocol. + * * @license * * ----------------------------------------------------------------------- @@ -142,15 +91,15 @@ extern int frescan_sa_init(frescan_sa_scenario_t *scenario, * frescan_sa_add_contract() - add a contract to the scenario * * @scenario: the scenario (in out) - * @contract: the new contract (in) * @ss: the preallocated ss identificator (in) * @node: the node this contract belongs to (in) + * @contract: the new contract (in) */ -extern int frescan_sa_add_contract(frescan_sa_scenario_t *scenario, - const frescan_contract_t *contract, - frescan_ss_t ss, - frescan_node_t node); +extern int frescan_sa_add_contract(frescan_sa_scenario_t *scenario, + frescan_ss_t ss, + frescan_node_t node, + const frsh_contract_t *contract); /** * frescan_sa_update_contract() - update a contract in the scenario @@ -159,14 +108,15 @@ extern int frescan_sa_add_contract(frescan_sa_scenario_t *scenario, * @ss: the ss identificator (in) * @node: the node this contract belongs to (in) * @contract: the values to update the contract (in) - * @old_contract: the values of the previous contract. Can be NULL (out) + * @old_contract: the values of the previous contract. if NULL + * no contract is returned (out) */ -extern int frescan_sa_update_contract(frescan_sa_scenario_t *scenario, - frescan_ss_t ss, - frescan_node_t node, - const frescan_contract_t *contract, - frescan_contract_t *old_contract); +extern int frescan_sa_update_contract(frescan_sa_scenario_t *scenario, + frescan_ss_t ss, + frescan_node_t node, + const frsh_contract_t *contract, + frsh_contract_t *old_contract); /** * frescan_sa_remove_contract() - remove a contract from the scenario @@ -184,32 +134,18 @@ extern int frescan_sa_remove_contract(frescan_sa_scenario_t *scenario, * frescan_sa_sched_test() - perform a scheduling test on the scenario * * @scenario: the scenario (in out) - * @success: if the scenario is schedulable or not (out) + * @is_schedulable: if the scenario is schedulable or not (out) */ extern int frescan_sa_sched_test(frescan_sa_scenario_t *scenario, - bool *success); + bool *is_schedulable); /** - * frescan_sa_spare_capacity() - distribute the remaining spare capacity + * frescan_sa_spare_capacity() - distribute the spare capacity * * @scenario: the scenario (in out) */ extern int frescan_sa_spare_capacity(frescan_sa_scenario_t *scenario); -/** - * frescan_sa_get_final_values() - get the final values - * - * @scenario: the scenario (in) - * @ss: the ss from which we want the final values (in) - * @node: the node this contract belongs to (in) - * @final_values: the final values (out) - */ - -extern int frescan_sa_get_final_values(const frescan_sa_scenario_t *scenario, - frescan_ss_t ss, - frescan_node_t node, - frescan_sa_final_values_t *final_values); - #endif // _FRESCAN_BWRES_ANALYSIS_H_ diff --git a/src_frescan/frescan_bwres_fna.c b/src_frescan/frescan_bwres_fna.c index 648a807..24c82e7 100644 --- a/src_frescan/frescan_bwres_fna.c +++ b/src_frescan/frescan_bwres_fna.c @@ -67,12 +67,9 @@ #include "frsh.h" /* frsh_resource_id_t, .. */ #include "frescan.h" /* frescan_init, ... */ -#include "frescan_data.h" /* frescan_contract_t, ... */ #include "frescan_bwres.h" /* frescan_bwres_init, ... */ #include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */ - -#undef ERROR -#include "frescan_debug.h" /* DEBUG, ERROR */ +#include "frescan_debug.h" /* DEBUG, FRESCAN_ERROR */ ////////////////////////////////////////////////////////////////////// // INITIALIZATION @@ -111,12 +108,12 @@ int frescan_fna_init(const frsh_resource_id_t resource_id) DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing FRESCAN\n"); ret = frescan_init(&init_params); - if (ret != 0) ERROR ("could not init FRESCAN"); + if (ret != 0) FRESCAN_ERROR ("could not init FRESCAN"); DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing BWRES\n"); ret = frescan_bwres_init(init_params.net); - if (ret != 0) ERROR ("could not init BWRES"); + if (ret != 0) FRESCAN_ERROR ("could not init BWRES"); return 0; } @@ -166,24 +163,10 @@ int frescan_fna_contract_negotiate int ret; bool accepted; frescan_ss_t ss; - frescan_contract_t frescan_contract; - - DEBUG(FRESCAN_FNA_ENABLE_DEBUG, - "frsh contract->frescan contract\n"); - - // NOTE: budget is stored as number of can frames in tv_sec - frescan_contract.min_values.budget = contract->budget_min.tv_sec; - frescan_contract.min_values.period = contract->period_max; - - frescan_contract.max_values.budget = contract->budget_max.tv_sec; - frescan_contract.max_values.period = contract->period_min; - - // TODO: put 0 if we want the sa module to assign the prios - frescan_contract.prio = contract->preemption_level; DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "calling frescan_bwres_negotiate\n"); ret = frescan_bwres_negotiate((frescan_network_t)resource_id, - &frescan_contract, + contract, &ss, &accepted); if (ret != 0) return -1; @@ -233,7 +216,7 @@ int frescan_fna_contract_renegotiate_sync const fna_vres_id_t vres, const frsh_contract_t *new_contract) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -285,7 +268,7 @@ int frescan_fna_contract_renegotiate_async frsh_signal_t signal_to_notify, frsh_signal_info_t signal_info) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -322,7 +305,7 @@ int frescan_fna_vres_get_renegotiation_status const fna_vres_id_t vres, frsh_renegotiation_status_t *renegotiation_status) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -351,7 +334,7 @@ int frescan_fna_vres_destroy (const frsh_resource_id_t resource_id, const fna_vres_id_t vres) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -381,7 +364,7 @@ int frescan_fna_vres_get_contract const fna_vres_id_t vres, frsh_contract_t *contract) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -410,7 +393,7 @@ int frescan_fna_vres_get_usage const fna_vres_id_t vres, struct timespec *usage) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -440,7 +423,7 @@ int frescan_fna_vres_get_remaining_budget const fna_vres_id_t vres, struct timespec *remaining_budget) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -472,7 +455,7 @@ int frescan_fna_vres_get_budget_and_period struct timespec *budget, struct timespec *period) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -520,7 +503,7 @@ int frescan_fna_resource_get_capacity const int importance, uint32_t *capacity) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -548,7 +531,7 @@ int frescan_fna_resource_get_total_weight const int importance, int *total_weight) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -583,7 +566,7 @@ int frescan_fna_vres_decrease_capacity const struct timespec new_budget, const struct timespec new_period) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -619,7 +602,7 @@ int frescan_fna_send_sync const void *msg, const size_t size) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -668,7 +651,7 @@ int frescan_fna_send_async ret = frescan_send(¶ms, (uint8_t *)msg, size); if (ret != 0) { - ERROR ("could not send message\n"); + FRESCAN_ERROR ("could not send message\n"); return -1; } @@ -736,7 +719,7 @@ int frescan_fna_receive_sync received_bytes, &frescan_from, &prio); if (ret != 0) { - ERROR ("error while receiving message"); + FRESCAN_ERROR ("error while receiving message"); return -1; } @@ -781,7 +764,7 @@ int frescan_fna_receive_async size_t *received_bytes, frsh_network_address_t *from) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -811,7 +794,7 @@ int frescan_fna_send_endpoint_get_status frsh_endpoint_network_status_t *network_status, frsh_protocol_status_t *protocol_status) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -866,7 +849,7 @@ int frescan_fna_receive_endpoint_get_status frsh_endpoint_network_status_t *network_status, frsh_protocol_status_t *protocol_status) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -906,7 +889,7 @@ int frescan_fna_network_get_max_message_size const frsh_network_address_t destination, size_t *max_size) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } diff --git a/src_frescan/frescan_bwres_frsh_fna.c b/src_frescan/frescan_bwres_frsh_fna.c index 154d1a4..1e6bd95 100644 --- a/src_frescan/frescan_bwres_frsh_fna.c +++ b/src_frescan/frescan_bwres_frsh_fna.c @@ -66,8 +66,6 @@ #include "frsh_fna.h" #include "frescan.h" - -#undef ERROR #include "frescan_debug.h" ////////////////////////////////////////////////////////////////////// @@ -167,7 +165,7 @@ int frsh_frescan_negotiation_messages_vres_renegotiate (const frsh_resource_id_t resource_id, const struct timespec *period) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -193,7 +191,7 @@ int frsh_frescan_negotiation_messages_vres_get_period (const frsh_resource_id_t resource_id, struct timespec *period) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -227,7 +225,7 @@ int frsh_frescan_service_thread_vres_renegotiate const struct timespec *period, bool *accepted) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } @@ -254,6 +252,6 @@ int frsh_frescan_service_thread_vres_get_budget_and_period struct timespec *budget, struct timespec *period) { - ERROR("not implemented\n"); + FRESCAN_ERROR("not implemented\n"); return -1; } diff --git a/src_frescan/frescan_bwres_messages.c b/src_frescan/frescan_bwres_messages.c index 4fea7a1..4c89972 100644 --- a/src_frescan/frescan_bwres_messages.c +++ b/src_frescan/frescan_bwres_messages.c @@ -72,6 +72,8 @@ #include "frescan_config.h" #include "frescan_debug.h" +#define FRESCAN_BWRES_MX_MSG_SIZE 3000 // TODO: adjust to the minimum + /** * frescan_messages_init() */ @@ -119,38 +121,59 @@ struct frescan_req_neg_message_t { frescan_request_type_t type; frescan_request_id_t req; frescan_ss_t ss; - frescan_contract_t contract; } __attribute__ ((packed)); static int frescan_request_to_neg_message(const frescan_request_data_t *data, uint8_t *msg) { + int ret; struct frescan_req_neg_message_t *neg_msg; + size_t req_size, contract_size; neg_msg = (struct frescan_req_neg_message_t *)msg; + req_size = sizeof(struct frescan_req_neg_message_t); neg_msg->type = FRESCAN_REQ_NEG; neg_msg->req = data->req; neg_msg->ss = data->ss; - neg_msg->contract = *(data->contract); - DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n", - neg_msg->type, neg_msg->req, neg_msg->ss); + ret = frsh_contract_marshal(data->contract, + msg + req_size, + FRESCAN_BWRES_MX_MSG_SIZE - req_size, + &contract_size); + if (ret != 0) { + FRESCAN_ERROR("frsh_contract_marshal return -1\n"); + return -1; + } + + DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d csize:%u\n", + neg_msg->type, neg_msg->req, neg_msg->ss, contract_size); - return sizeof(struct frescan_req_neg_message_t); + return req_size + contract_size; } static int frescan_neg_message_to_request(const uint8_t *msg, - frescan_request_data_t *data) + frescan_request_data_t *data, + size_t size) { + int ret; struct frescan_req_neg_message_t *neg_msg; + size_t req_size; neg_msg = (struct frescan_req_neg_message_t *)msg; + req_size = sizeof(struct frescan_req_neg_message_t); data->type = FRESCAN_REQ_NEG; data->req = neg_msg->req; data->ss = neg_msg->ss; - *(data->contract) = neg_msg->contract; + + ret = frsh_contract_unmarshal(data->contract, + msg + req_size, // pointer to contract + size - req_size); // size marshal ' ' + if (ret != 0) { + FRESCAN_ERROR("frsh_contract_unmarshal return -1\n"); + return -1; + } DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n", data->type, data->req, data->ss); @@ -180,38 +203,59 @@ struct frescan_req_reneg_message_t { frescan_request_type_t type; frescan_request_id_t req; frescan_ss_t ss; - frescan_contract_t contract; } __attribute__ ((packed)); static int frescan_request_to_reneg_message(const frescan_request_data_t *data, uint8_t *msg) { + int ret; + size_t req_size, contract_size; struct frescan_req_reneg_message_t *reneg_msg; reneg_msg = (struct frescan_req_reneg_message_t *)msg; + req_size = sizeof(struct frescan_req_reneg_message_t); reneg_msg->type = FRESCAN_REQ_RENEG; reneg_msg->req = data->req; reneg_msg->ss = data->ss; - reneg_msg->contract = *(data->contract); - DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n", - reneg_msg->type, reneg_msg->req, reneg_msg->ss); + ret = frsh_contract_marshal(data->contract, + msg + req_size, + FRESCAN_BWRES_MX_MSG_SIZE - req_size, + &contract_size); + if (ret != 0) { + FRESCAN_ERROR("frsh_contract_marshal return -1\n"); + return -1; + } + + DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d csize:%u\n", + reneg_msg->type, reneg_msg->req, reneg_msg->ss, contract_size); - return sizeof(struct frescan_req_reneg_message_t); + return req_size + contract_size; } static int frescan_reneg_message_to_request(const uint8_t *msg, - frescan_request_data_t *data) + frescan_request_data_t *data, + size_t size) { + int ret; struct frescan_req_reneg_message_t *reneg_msg; + size_t req_size; reneg_msg = (struct frescan_req_reneg_message_t *)msg; + req_size = sizeof(struct frescan_req_neg_message_t); data->type = FRESCAN_REQ_RENEG; data->req = reneg_msg->req; data->ss = reneg_msg->ss; - *(data->contract) = reneg_msg->contract; + + ret = frsh_contract_unmarshal(data->contract, + msg + req_size, + size - req_size); + if (ret != 0) { + FRESCAN_ERROR("frsh_contract_unmarshal return -1\n"); + return -1; + } DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n", data->type, data->req, data->ss); @@ -270,6 +314,65 @@ static int frescan_cancel_message_to_request(const uint8_t *msg, return 0; } +/** + * + * FRESCAN_REP_CHANGE MESSAGE + * ========================== + * This message is sent from the MASTER to a slave as a reply to a + * FRESCAN_REQ_NEG or a FRESCAN_REQ_RENEG, to say if they were admited. + * It contains the type 'REPNEG', the request ID of the slave, a + * return value to say if the contract is admited or not, and the final + * values if it was admited + * + * +----------------------------------------------+ + * | 'REPNEG' | REQ | RETURN_VALUE | FINAL_VALUES | + * +----------------------------------------------+ + * + */ + +struct frescan_rep_neg_message_t { + frescan_request_type_t type; + frescan_request_id_t req; + frescan_request_retval_t return_value; + frescan_server_params_t final_values; +} __attribute__ ((packed)); + +static int frescan_request_to_repneg_message(const frescan_request_data_t *data, + uint8_t *msg) +{ + struct frescan_rep_neg_message_t *repneg_msg; + + repneg_msg = (struct frescan_rep_neg_message_t *)msg; + + repneg_msg->type = FRESCAN_REP_NEG; + repneg_msg->req = data->req; + repneg_msg->return_value = data->return_value; + repneg_msg->final_values = data->final_values; + + DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n", + repneg_msg->type, repneg_msg->req, repneg_msg->return_value); + + return sizeof(struct frescan_rep_neg_message_t); +} + +static int frescan_repneg_message_to_request(const uint8_t *msg, + frescan_request_data_t *data) +{ + struct frescan_rep_neg_message_t *repneg_msg; + + repneg_msg = (struct frescan_rep_neg_message_t *)msg; + + data->type = FRESCAN_REP_NEG; + data->req = repneg_msg->req; + data->return_value = repneg_msg->return_value; + data->final_values = repneg_msg->final_values; + + DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n", + data->type, data->req, data->return_value); + + return 0; +} + /** * * FRESCAN_REP_NEG MESSAGE @@ -290,7 +393,7 @@ struct frescan_rep_neg_message_t { frescan_request_type_t type; frescan_request_id_t req; frescan_request_retval_t return_value; - frescan_sa_final_values_t final_values; + frescan_server_params_t final_values; } __attribute__ ((packed)); static int frescan_request_to_repneg_message(const frescan_request_data_t *data, @@ -303,6 +406,7 @@ static int frescan_request_to_repneg_message(const frescan_request_data_t *data, repneg_msg->type = FRESCAN_REP_NEG; repneg_msg->req = data->req; repneg_msg->return_value = data->return_value; + // TODO: use final values only if it was accepted! repneg_msg->final_values = data->final_values; DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n", @@ -321,6 +425,7 @@ static int frescan_repneg_message_to_request(const uint8_t *msg, data->type = FRESCAN_REP_NEG; data->req = repneg_msg->req; data->return_value = repneg_msg->return_value; + // TODO: use final values only if it was accepted! data->final_values = repneg_msg->final_values; DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n", @@ -342,7 +447,7 @@ static int frescan_repneg_message_to_request(const uint8_t *msg, int frescan_messages_send_request(const frescan_request_data_t *req_data) { int ret; - uint8_t msg[2000]; // TODO: use a constant for max neg message size + uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE]; size_t size; switch(req_data->type) { @@ -358,12 +463,16 @@ int frescan_messages_send_request(const frescan_request_data_t *req_data) size = frescan_request_to_cancel_message(req_data, msg); send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE; break; + case FRESCAN_REP_CHANGE: + size = frescan_request_to_repchange_message(req_data, msg); + send_params[req_data->net].to = req_data->request_node; + break; case FRESCAN_REP_NEG: size = frescan_request_to_repneg_message(req_data, msg); send_params[req_data->net].to = req_data->request_node; break; default: - ERROR("request type not supported\n"); + FRESCAN_ERROR("request type not supported\n"); return -1; } @@ -390,7 +499,7 @@ int frescan_messages_recv_request(frescan_network_t net, frescan_request_id_t *req) { int ret; - uint8_t msg[2000]; // TODO: use a constant with the max neg message size + uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE]; size_t recv_bytes; frescan_node_t from; frescan_prio_t prio; @@ -420,15 +529,21 @@ int frescan_messages_recv_request(frescan_network_t net, switch(*((frescan_request_type_t *)msg)) { case FRESCAN_REQ_NEG: - return frescan_neg_message_to_request(msg, req_data); + return frescan_neg_message_to_request(msg, + req_data, + recv_bytes); case FRESCAN_REQ_RENEG: - return frescan_reneg_message_to_request(msg, req_data); + return frescan_reneg_message_to_request(msg, + req_data, + recv_bytes); case FRESCAN_REQ_CANCEL: return frescan_cancel_message_to_request(msg, req_data); + case FRESCAN_REP_CHANGE: + return frescan_repchange_message_to_request(msg, req_data); case FRESCAN_REP_NEG: return frescan_repneg_message_to_request(msg, req_data); default: - ERROR("request type %X not supported\n", + FRESCAN_ERROR("request type %X not supported\n", *(frescan_request_type_t *)msg); return -1; } diff --git a/src_frescan/frescan_bwres_mode_change.c b/src_frescan/frescan_bwres_mode_change.c new file mode 100644 index 0000000..30328c4 --- /dev/null +++ b/src_frescan/frescan_bwres_mode_change.c @@ -0,0 +1,201 @@ +/*! + * @file frescan_bwres_analysis.h + * + * @brief FRESCAN bandwith reservation layer: mode change protocol + * + * @version 0.02 + * + * @date 19-Jul-2008 + * + * @author Daniel Sangorrin + * + * @comments + * + * This module contains the mode change protocol + * + * @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 "frescan_bwres_mode_change.h" +#include "frescan_data.h" +#include + +/** + * frescan_bwres_mode_change_protocol() - performs the mode change + * + * Follow the mode change protocol described in the paper. + * + */ + +int frescan_bwres_mode_change_protocol(frescan_request_data_t *req_data) +{ + int ret; + 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; + + for(node=0; nodenet]. + mode_change_budget_inc_list_head[node]); + + INIT_LIST_HEAD(&the_networks[req_data->net]. + mode_change_budget_dec_list_head[node]); + } + + max_period_in_budget_dec = (frsh_sa_time_t)0; + max_period_in_budget_inc = (frsh_sa_time_t)0; + + list_for_each_entry + (vres, + &the_networks[req_data->net].scenario.vres_head.list, + list) + { + sa_vres_data = &the_networks[req_data->net]. + scenario.fsa_scenario.sa_vres_alloc + [vres->fsa_vres_global_id]; + + vres->mode_change_type = 0; + + if (sa_vres_data->c > vres->old_c) { + vres->mode_change_type |= FRESCAN_SA_BUDGET_INC; + + if (sa_vres_data->t > max_period_in_budget_inc) { + max_period_in_budget_inc = sa_vres_data->t; + } + + list_add_tail + (&(vres->mode_change_list), + &(the_networks[req_data->net]. + mode_change_budget_inc_list_head[vres->node])); + } else { + vres->mode_change_type |= FRESCAN_SA_BUDGET_DEC; + + if (sa_vres_data->t > max_period_in_budget_dec) { + max_period_in_budget_dec = sa_vres_data->t; + } + + list_add_tail + (&(vres->mode_change_list), + &(the_networks[req_data->net]. + mode_change_budget_dec_list_head[vres->node])); + } + + if (sa_vres_data->t > vres->old_t) { + vres->mode_change_type |= FRESCAN_SA_PERIOD_INC; + } else { + vres->mode_change_type |= FRESCAN_SA_PERIOD_DEC; + } + + if (sa_vres_data->p > vres->old_p) { + vres->mode_change_type |= FRESCAN_SA_PRIO_INC; + } else { + vres->mode_change_type |= FRESCAN_SA_PRIO_DEC; + } + + vres->old_c = sa_vres_data->c; + vres->old_t = sa_vres_data->t; + vres->old_p = sa_vres_data->p; + } + + // mode change for B- members + for(node=FRESCAN_MX_NODES-1; node>=0; node--) { + 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 = ... + + + + + + + } 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; + } + } + } + + if (node == FRESCAN_NEG_MASTER_NODE) { + beginning = clock + // delay + clock_nanosleep(absolute, beginning+period + // commmit + list_del lo que ha disminuido + } + } + + // wait the time needed to keep schedulability + + + // mode change for B+ members + + + return 0; +} diff --git a/src_frescan/frescan_bwres_mode_change.h b/src_frescan/frescan_bwres_mode_change.h new file mode 100644 index 0000000..8957852 --- /dev/null +++ b/src_frescan/frescan_bwres_mode_change.h @@ -0,0 +1,83 @@ +/*! + * @file frescan_bwres_analysis.h + * + * @brief FRESCAN bandwith reservation layer: mode change protocol + * + * @version 0.02 + * + * @date 19-Jul-2008 + * + * @author Daniel Sangorrin + * + * @comments + * + * This module contains the mode change protocol + * + * @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. + * ----------------------------------------------------------------------- + * + */ + +#ifndef _FRESCAN_BWRES_MODE_CHANGE_H_ +#define _FRESCAN_BWRES_MODE_CHANGE_H_ + +#include "frescan.h" +#include "frescan_data.h" +#include "frescan_bwres_requests.h" + +/** + * frescan_bwres_mode_change_protocol() - performs the mode change + * + * @net: the network (in) + */ + +extern int frescan_bwres_mode_change_protocol(frescan_request_data_t *req_data); + +#endif // _FRESCAN_BWRES_MODE_CHANGE_H_ diff --git a/src_frescan/frescan_bwres_requests.h b/src_frescan/frescan_bwres_requests.h index c7f98f8..d6834c9 100644 --- a/src_frescan/frescan_bwres_requests.h +++ b/src_frescan/frescan_bwres_requests.h @@ -68,8 +68,8 @@ #define _FRESCAN_BWRES_REQUESTS_H_ #include -#include "frescan_data.h" // frescan_contract_t #include "frescan_bwres_robjs.h" // frescan_robj_id_t +#include "frescan_data.h" // frescan_ss_t /** * frescan_request_data_t @@ -95,7 +95,8 @@ typedef enum { FRESCAN_REQ_NEG = 0, // Negotiate a contract FRESCAN_REQ_RENEG = 1, // Renegotiate a contract FRESCAN_REQ_CANCEL = 2, // Cancel a contract - FRESCAN_REP_NEG = 3, // Reply to (Re)Negotiate a contract + FRESCAN_REP_CHANGE = 3, // Change values due to spare capacity dist + FRESCAN_REP_NEG = 4, // Reply to (Re)Negotiate a contract } frescan_request_type_t; typedef enum { @@ -105,12 +106,12 @@ typedef enum { typedef struct { frescan_request_type_t type; - frescan_contract_t *contract; + frsh_contract_t *contract; frescan_ss_t ss; frescan_node_t request_node; frescan_request_id_t req; frescan_request_retval_t return_value; - frescan_sa_final_values_t final_values; + frescan_server_params_t final_values; frescan_network_t net; frescan_robj_id_t robj; } frescan_request_data_t; diff --git a/src_frescan/frescan_bwres_robjs.c b/src_frescan/frescan_bwres_robjs.c index 4366e2e..d2784da 100644 --- a/src_frescan/frescan_bwres_robjs.c +++ b/src_frescan/frescan_bwres_robjs.c @@ -238,7 +238,7 @@ int frescan_bwres_robjs_signal(frescan_robj_id_t id) return 0; locked_error: - ERROR("locked error %d\n", err); + FRESCAN_ERROR("locked error %d\n", err); fosa_mutex_unlock(&the_reply_objects[id].mutex); return err; } diff --git a/src_frescan/frescan_bwres_threads.c b/src_frescan/frescan_bwres_threads.c index cde05b0..e4efcc4 100644 --- a/src_frescan/frescan_bwres_threads.c +++ b/src_frescan/frescan_bwres_threads.c @@ -70,6 +70,7 @@ #include "frescan_bwres_messages.h" #include "frescan_bwres_requests.h" #include "frescan_bwres_analysis.h" +#include "frescan_bwres_mode_change.h" #include "frescan_config.h" #include "frescan_debug.h" #include "frescan_data.h" @@ -180,7 +181,7 @@ static void *frescan_manager_thread(void *arg) frescan_manager_repneg(req_data); break; default: - ERROR("request type not supported\n"); + FRESCAN_ERROR("request type not supported\n"); assert(0); } @@ -226,48 +227,70 @@ static void frescan_manager_neg(frescan_request_data_t *req_data) DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "negotiation request\n"); if (the_networks[req_data->net].local_node == FRESCAN_NEG_MASTER_NODE) { - // scheduling analysis + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "add contract to scenario\n"); + ret = frescan_sa_add_contract (&the_networks[req_data->net].scenario, - req_data->contract, req_data->ss, - req_data->request_node); + req_data->request_node, + req_data->contract); + assert(ret == 0); + + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "assign priorities\n"); + + ret = frsh_sa_assign_priorities + (&the_networks[req_data->net].scenario); assert(ret == 0); + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "perform sched analysis\n"); + ret = frescan_sa_sched_test (&the_networks[req_data->net].scenario, &accepted); assert(ret == 0); if (accepted) { - ret = frescan_sa_get_final_values - (&the_networks[req_data->net].scenario, - req_data->ss, - req_data->request_node, - &req_data->final_values); + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "schedulable! distribute spare capacity\n"); + + ret = frescan_sa_spare_capacity + (&the_networks[req_data->net].scenario); assert(ret == 0); + req_data->return_value = FRESCAN_REQ_ACCEPTED; + + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "perform the mode change protocol!\n"); + + ret = frescan_bwres_mode_change_protocol(req_data); + assert(ret == 0); } else { + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "not schedulable!\n"); + ret = frescan_sa_remove_contract (&the_networks[req_data->net].scenario, req_data->ss, req_data->request_node); assert(ret == 0); - req_data->return_value = FRESCAN_REQ_NOT_ACCEPTED; - } - // signal or reply the results - if (req_data->request_node == FRESCAN_NEG_MASTER_NODE) { - DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "master local\n"); - ret = frescan_bwres_robjs_signal(req_data->robj); - assert(ret == 0); - } else { - DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, - "master external, sending reply\n"); + req_data->return_value = FRESCAN_REQ_NOT_ACCEPTED; - req_data->type = FRESCAN_REP_NEG; - ret = frescan_messages_send_request(req_data); - assert(ret == 0); + if (req_data->request_node == FRESCAN_NEG_MASTER_NODE) { + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "signal local request\n"); + ret = frescan_bwres_robjs_signal(req_data->robj); + assert(ret == 0); + } else { + 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 { DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, @@ -284,8 +307,8 @@ static void frescan_manager_neg(frescan_request_data_t *req_data) static void frescan_manager_reneg(frescan_request_data_t *req_data) { int ret; - bool accepted; - frescan_contract_t old_contract; + bool is_schedulable; + frsh_contract_t old_contract; DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "renegotiation request\n"); @@ -299,19 +322,36 @@ static void frescan_manager_reneg(frescan_request_data_t *req_data) &old_contract); assert(ret == 0); + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "assign priorities\n"); + + ret = frsh_sa_assign_priorities + (&the_networks[req_data->net].scenario); + assert(ret == 0); + + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "perform sched analysis\n"); + ret = frescan_sa_sched_test (&the_networks[req_data->net].scenario, - &accepted); + &is_schedulable); assert(ret == 0); if (accepted) { - ret = frescan_sa_get_final_values - (&the_networks[req_data->net].scenario, - req_data->ss, - req_data->request_node, - &req_data->final_values); + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "schedulable! distribute spare capacity\n"); + + ret = frescan_sa_spare_capacity + (&the_networks[req_data->net].scenario); assert(ret == 0); + req_data->return_value = FRESCAN_REQ_ACCEPTED; + + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "perform the mode change protocol!\n"); + + ret = frescan_bwres_mode_change_protocol(req_data); + assert(ret == 0); } else { ret = frescan_sa_update_contract (&the_networks[req_data->net].scenario, @@ -328,13 +368,6 @@ static void frescan_manager_reneg(frescan_request_data_t *req_data) DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "master local\n"); ret = frescan_bwres_robjs_signal(req_data->robj); assert(ret == 0); - } else { - DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, - "master external, sending reply\n"); - - req_data->type = FRESCAN_REP_NEG; - ret = frescan_messages_send_request(req_data); - assert(ret == 0); } } else { DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, @@ -351,6 +384,7 @@ static void frescan_manager_reneg(frescan_request_data_t *req_data) static void frescan_manager_cancel(frescan_request_data_t *req_data) { int ret; + bool is_schedulable; DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "cancel request\n"); @@ -360,6 +394,33 @@ static void frescan_manager_cancel(frescan_request_data_t *req_data) req_data->ss, req_data->request_node); assert(ret == 0); + + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "assign priorities\n"); + + ret = frsh_sa_assign_priorities + (&the_networks[req_data->net].scenario); + assert(ret == 0); + + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "perform sched analysis\n"); + + ret = frescan_sa_sched_test + (&the_networks[req_data->net].scenario, + &is_schedulable); + assert(ret == 0); + + assert(is_schedulable == true); + + DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, + "redistribute spare capacity\n"); + + ret = frescan_sa_spare_capacity + (&the_networks[req_data->net].scenario); + assert(ret == 0); + + ret = frescan_bwres_mode_change_protocol(req_data); + assert(ret == 0); } else { DEBUG(FRESCAN_MANAGER_ENABLE_DEBUG, "send cancel request to master\n"); diff --git a/src_frescan/frescan_data.h b/src_frescan/frescan_data.h index f42b330..28962ba 100644 --- a/src_frescan/frescan_data.h +++ b/src_frescan/frescan_data.h @@ -82,6 +82,9 @@ #include "frescan_config.h" // FRESCAN_MLOCK_T, FRESCAN_MX_XXX #include "frescan_packets.h" // frescan_packet_t +#include "frsh.h" // for frsh_contract_t +#include "fsa.h" // for frsh_sa_scenario_t + /** * frescan_repl_op_t - a replenishment operation * @@ -103,16 +106,12 @@ typedef struct { * * @budget: the budget in CAN 8-byte frames * @period: the replenishment period for the server - * @prio: the priority for the server TODO: this should be a return value + * @prio: the priority of the server */ typedef struct { frescan_budget_t budget; struct timespec period; -} frescan_budget_period_t; - -typedef struct { - frescan_budget_period_t values; frescan_prio_t prio; } frescan_server_params_t; @@ -132,16 +131,16 @@ typedef struct { typedef struct { frescan_server_params_t params; - frescan_network_t net; - frescan_ss_t id; - frescan_budget_t current_budget; - frescan_prio_t current_priority; - frescan_budget_t pending_packets; - frescan_repl_op_t replenishments; - timer_t repl_timer; - struct timespec act_time; - frescan_packet_t packet_list; - struct list_head servers_list; + frescan_network_t net; + frescan_ss_t id; + frescan_budget_t current_budget; + frescan_prio_t current_priority; + frescan_budget_t pending_packets; + frescan_repl_op_t replenishments; + timer_t repl_timer; + struct timespec act_time; + frescan_packet_t packet_list; + struct list_head servers_list; } frescan_server_data_t; /** @@ -153,40 +152,54 @@ extern freelist_t the_servers_pool_freelist[FRESCAN_MX_NETWORKS]; extern frescan_server_data_t the_active_servers[FRESCAN_MX_NETWORKS]; /** - * frescan_contract_t + * frescan_sa_vres_t - a frescan vres + * + * @contract: the contract of the virtual resource + * @node: the node where the vres belongs to + * @ss: the sporadic server identifier + * @list: the list of vres. Note that this is the list of all the vres + * in the network instace. As this is a master-slave protocol the master + * knows everything about the contracts of the rest of nodes. */ +typedef enum { + FRESCAN_SA_PERIOD_DEC = 1<<5, + FRESCAN_SA_PERIOD_INC = 1<<4, + FRESCAN_SA_BUDGET_DEC = 1<<3, + FRESCAN_SA_BUDGET_INC = 1<<2, + FRESCAN_SA_PRIO_DEC = 1<<1, + FRESCAN_SA_PRIO_INC = 1 +} frescan_sa_mode_change_type_t; + typedef struct { - frescan_budget_period_t min_values; - frescan_budget_period_t max_values; - frescan_prio_t prio; -} frescan_contract_t; + frsh_contract_t contract; + frescan_node_t node; + frescan_ss_t ss; + frsh_sa_vres_id_t fsa_vres_global_id; + struct list_head list; + // mode change variables + frsh_sa_time_t old_c; + frsh_sa_time_t old_t; + frsh_sa_prio_t old_p; + frescan_sa_mode_change_type_t mode_change_type; + struct list_head mode_change_list; +} frescan_sa_vres_t; /** - * frescan_sa_xxx scheduling analysis types + * frescan_sa_scenario_t - the scheduling analysis scenario */ -typedef struct { - frescan_prio_t server_prio; -} frescan_sa_final_values_t; - -typedef struct { - frescan_contract_t contract; - frescan_node_t node; - frescan_ss_t ss; - frescan_sa_final_values_t final_values; - struct list_head list; -} frescan_sa_contract_t; - typedef struct { frescan_prio_t max_prio; frescan_prio_t min_prio; } frescan_sa_init_params_t; typedef struct { - frescan_sa_contract_t contracts[FRESCAN_MX_NODES][FRESCAN_MX_IDS]; - frescan_sa_contract_t contracts_head; frescan_sa_init_params_t init_params; + frescan_sa_vres_t vres_pool[FRESCAN_MX_NODES][FRESCAN_MX_IDS]; + frescan_sa_vres_t vres_head; + freelist_t fsa_id_freelist; + frsh_sa_scenario_t fsa_scenario; } frescan_sa_scenario_t; /** @@ -272,6 +285,8 @@ typedef struct { frescan_packet_t *id_queues[FRESCAN_MX_NODES][FRESCAN_MX_IDS]; // TODO: alloc at init frescan_packet_t *id_fp_queues[FRESCAN_MX_NODES][FRESCAN_MX_PRIOS]; // TODO: alloc at init frescan_sa_scenario_t scenario; + struct list_head mode_change_budget_inc_list_head[FRESCAN_MX_NODES]; + struct list_head mode_change_budget_dec_list_head[FRESCAN_MX_NODES]; } frescan_network_data_t; extern frescan_network_data_t the_networks[FRESCAN_MX_NETWORKS]; diff --git a/src_frescan/frescan_debug.h b/src_frescan/frescan_debug.h index e30362d..3d1121f 100644 --- a/src_frescan/frescan_debug.h +++ b/src_frescan/frescan_debug.h @@ -79,8 +79,8 @@ **/ #define DEBUG(enable,x,args...) if(enable) printc("DEBUG (%s): " x, __func__ , ##args) -#define ERROR(x,args...) {printe("ERROR (%s:%u): " x, __func__ , __LINE__ , ##args); exit(-1);} -#define WARNING(x,args...) printe("WARNING (%s): " x, __func__ , ##args) +#define FRESCAN_ERROR(x,args...) {printe("ERROR (%s:%u): " x, __func__ , __LINE__ , ##args); exit(-1);} +#define FRESCAN_WARNING(x,args...) printe("WARNING (%s): " x, __func__ , ##args) /** * DEBUGGING FLAGS to enable/disable debugging messages diff --git a/src_frescan/frescan_hw_buffer.c b/src_frescan/frescan_hw_buffer.c index 40c50e9..3608cf5 100644 --- a/src_frescan/frescan_hw_buffer.c +++ b/src_frescan/frescan_hw_buffer.c @@ -74,7 +74,7 @@ #include // memcpy #include "frescan_data.h" // the_networks -#include "frescan_debug.h" // DEBUG, ERROR +#include "frescan_debug.h" // DEBUG, FRESCAN_ERROR #include "frescan_servers.h" // frescan_servers_get_highest_prio #include "frescan_queues.h" // frescan_pqueue_xxx, frescan_servers_dequeue #include "frescan_id.h" // frescan_id_set_field @@ -97,7 +97,7 @@ int frescan_hw_buffer_abort(frescan_network_t net) ret = ioctl(the_networks[net].fd, CAN_IOCTL_ABORT_FRAME, NULL); if (ret == -1) { - ERROR ("could not abort the frame\n"); + FRESCAN_ERROR ("could not abort the frame\n"); return -1; } @@ -159,7 +159,7 @@ int frescan_hw_buffer_update(frescan_network_t net) DEBUG(FRESCAN_HW_BUFFER_ENABLE_DEBUG,"abort frame\n"); ret = frescan_hw_buffer_abort(net); if (ret != 0) { - ERROR ("could not abort frame\n"); + FRESCAN_ERROR ("could not abort frame\n"); return ret; } return 0; @@ -209,7 +209,7 @@ int frescan_hw_buffer_update(frescan_network_t net) sizeof(struct can_frame_t)); if (ret != sizeof(struct can_frame_t)) { - ERROR ("could not send frame\n"); + FRESCAN_ERROR ("could not send frame\n"); return ret; } diff --git a/src_frescan/frescan_packets.c b/src_frescan/frescan_packets.c index c030a5e..c404225 100644 --- a/src_frescan/frescan_packets.c +++ b/src_frescan/frescan_packets.c @@ -110,7 +110,7 @@ frescan_packet_t *frescan_packets_alloc() { pos = freelist_alloc(&the_packet_pool_freelist); if (pos == -1) { - ERROR("could not allocate packet\n"); + FRESCAN_ERROR("could not allocate packet\n"); return NULL; } diff --git a/src_frescan/frescan_queues.c b/src_frescan/frescan_queues.c index b20b067..2206cd6 100644 --- a/src_frescan/frescan_queues.c +++ b/src_frescan/frescan_queues.c @@ -89,7 +89,7 @@ static inline frescan_prio_queue_t *frescan_pqueue_create(uint32_t max_prio, pq = (frescan_prio_queue_t *)malloc(sizeof(frescan_prio_queue_t)); if (pq == NULL) { - ERROR("could not allocate memory for prio queue\n"); + FRESCAN_ERROR("could not allocate memory for prio queue\n"); return NULL; } @@ -98,7 +98,7 @@ static inline frescan_prio_queue_t *frescan_pqueue_create(uint32_t max_prio, ret = sem_init (&pq->sem, 0, 0); if (ret != 0) { - ERROR("could not init the semaphore\n"); + FRESCAN_ERROR("could not init the semaphore\n"); free(pq); return NULL; } @@ -133,7 +133,7 @@ int frescan_queues_init(frescan_queues_t *queues, params->net); if (queues->tx_fp_queue == NULL) { - ERROR("could not allocate memory for tx fp queue\n"); + FRESCAN_ERROR("could not allocate memory for tx fp queue\n"); return -1; } @@ -143,7 +143,8 @@ int frescan_queues_init(frescan_queues_t *queues, sizeof(frescan_prio_queue_t *)); if (queues->rx_channel_queues == NULL) { - ERROR("could not allocate memory for receiving channels\n"); + FRESCAN_ERROR + ("could not allocate memory for receiving channels\n"); return -1; } @@ -162,7 +163,8 @@ int frescan_queues_init(frescan_queues_t *queues, (max_prio, params->net); if (queues->rx_channel_queues[i] == NULL) { - ERROR("could not allocate memory for rx pq %d\n", i); + FRESCAN_ERROR + ("could not allocate memory for rx pq %d\n", i); return -1; } } @@ -183,7 +185,7 @@ int frescan_pqueue_enqueue(frescan_prio_queue_t *pqueue, int ret; if (prio >= pqueue->max_prio) { - ERROR("priority of the packet is too high\n"); + FRESCAN_ERROR("priority of the packet is too high\n"); return -1; } @@ -211,7 +213,7 @@ int frescan_pqueue_requeue(frescan_prio_queue_t *pqueue, int ret; if (prio >= pqueue->max_prio) { - ERROR("priority of the packet is too high\n"); + FRESCAN_ERROR("priority of the packet is too high\n"); return -1; } @@ -407,7 +409,7 @@ int frescan_servers_dequeue(frescan_network_t net, server = &the_servers_pool[net][id]; if (list_empty(&server->packet_list.fifo_list)) { - ERROR("no packet in server %d fifo list\n", id); + FRESCAN_ERROR("no packet in server %d fifo list\n", id); return -1; } diff --git a/src_frescan/frescan_servers.c b/src_frescan/frescan_servers.c index 04fd14f..c133ee4 100644 --- a/src_frescan/frescan_servers.c +++ b/src_frescan/frescan_servers.c @@ -72,10 +72,10 @@ #include "frescan_servers_replenishments.h" // frescan_replenishments_xxx #include "frescan_debug.h" #include "frescan_data.h" -#include -#include #include #include +#include +#include "fosa_time_timespec.h" // smaller_timespec /** * frescan_servers_init() - initialize server structures @@ -98,7 +98,7 @@ int frescan_servers_init(frescan_network_t net) ret = frescan_replenishments_init(net); if (ret != 0) { - ERROR("could not initialize the replenishments\n"); + FRESCAN_ERROR("could not initialize the replenishments\n"); return -1; } @@ -128,7 +128,7 @@ int frescan_servers_create(frescan_network_t net, FRESCAN_RELEASE_LOCK(&the_networks[net].lock); if (pos == -1) { - ERROR("could not allocate servers\n"); + FRESCAN_ERROR("could not allocate servers\n"); return -1; } @@ -139,7 +139,7 @@ int frescan_servers_create(frescan_network_t net, server->net = net; server->id = *id; server->params = *params; - server->current_budget = params->values.budget; + server->current_budget = params->budget; server->current_priority = params->prio; server->pending_packets = 0; @@ -151,7 +151,7 @@ int frescan_servers_create(frescan_network_t net, // allocate the replenishment capacity queue INIT_LIST_HEAD(&server->replenishments.repl_list); - for (i=0; i < params->values.budget; i++) { + for (i=0; i < params->budget; i++) { repl = frescan_repl_op_alloc(); repl->when = server->act_time; repl->amount = 1; @@ -166,13 +166,13 @@ int frescan_servers_create(frescan_network_t net, ret = timer_create (CLOCK_MONOTONIC, &evp, &server->repl_timer); if (ret != 0) { - ERROR("could not create timer\n"); + FRESCAN_ERROR("could not create timer\n"); return ret; } DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "server created, id:%u budget:%u prio:%u\n", - *id, server->params.values.budget, server->params.prio); + *id, server->params.budget, server->params.prio); return 0; } @@ -211,7 +211,7 @@ int frescan_servers_destroy(frescan_network_t net, frescan_ss_t id) ret = timer_delete (the_servers_pool[net][id].repl_timer); if (ret != 0) { - ERROR("could not delete timer\n"); + FRESCAN_ERROR("could not delete timer\n"); return ret; } @@ -221,7 +221,7 @@ int frescan_servers_destroy(frescan_network_t net, frescan_ss_t id) ret = freelist_free(&the_servers_pool_freelist[net], id); FRESCAN_RELEASE_LOCK(&the_networks[net].lock); if (ret != 0) { - ERROR("could not free server data from pool\n"); + FRESCAN_ERROR("could not free server data from pool\n"); return ret; } @@ -330,7 +330,7 @@ int frescan_servers_frame_sent(frescan_network_t net, server = &the_servers_pool[net][id]; if (server->current_priority != FRESCAN_BACKGROUND_PRIO) { - if (smaller_timespec(&packet->timestamp, &server->act_time)) { + if (smaller_timespec(packet->timestamp, server->act_time)) { repl_time = &server->act_time; } else { repl_time = &packet->timestamp; diff --git a/src_frescan/frescan_servers.h b/src_frescan/frescan_servers.h index e9834b4..57868bb 100644 --- a/src_frescan/frescan_servers.h +++ b/src_frescan/frescan_servers.h @@ -73,7 +73,6 @@ #include "frescan.h" // frescan_prio_t, frescan_ss_t #include "frescan_packets.h" // frescan_packet_t -#include // struct timespec #include "frescan_data.h" /** diff --git a/src_frescan/frescan_servers_replenishments.c b/src_frescan/frescan_servers_replenishments.c index 04202a9..df3b516 100644 --- a/src_frescan/frescan_servers_replenishments.c +++ b/src_frescan/frescan_servers_replenishments.c @@ -72,13 +72,12 @@ #include // freelist_t #include // list_add_tail -#include #include "frescan_servers_replenishments.h" #include "frescan_config.h" // FRESCAN_MX_REPL_OPS -#include "frescan_debug.h" // ERROR +#include "frescan_debug.h" // FRESCAN_ERROR #include "frescan_data.h" // frescan_repl_op_t -#include "fosa_threads_and_signals.h" // fosa_thread_attr_init... +#include "fosa.h" // fosa_thread_attr_init, smaller_timespec, incr_timespec #if (FRESCAN_MEASURE_REPL_TH || FRESCAN_MEASURE_REPL_PROGRAM) #include @@ -114,7 +113,7 @@ frescan_repl_op_t *frescan_repl_op_alloc() pos = freelist_alloc(&the_repl_op_pool_freelist); if (pos == -1) { - ERROR("could not allocate repl op\n"); + FRESCAN_ERROR("could not allocate repl op\n"); return NULL; } the_repl_op_pool[pos].pool_pos = pos; // to know how to free it @@ -204,7 +203,7 @@ int frescan_replenishments_init(frescan_network_t net) ret = frescan_repl_op_init(); if (ret != 0) { - ERROR("could not init repl_op pool\n"); + FRESCAN_ERROR("could not init repl_op pool\n"); return ret; } @@ -212,7 +211,7 @@ int frescan_replenishments_init(frescan_network_t net) ret = fosa_set_accepted_signals(signal_set, 1); if (ret != 0) { - ERROR("could not set the repl signal\n"); + FRESCAN_ERROR("could not set the repl signal\n"); return ret; } @@ -229,13 +228,13 @@ int frescan_replenishments_init(frescan_network_t net) ret = fosa_thread_attr_init(&attr); if (ret != 0) { - ERROR("could not init thread attributes\n"); + FRESCAN_ERROR("could not init thread attributes\n"); return ret; } ret = fosa_thread_attr_set_prio(&attr, FRESCAN_REPL_THREAD_PRIO); if (ret != 0) { - ERROR("could not set repl thread prio %d\n", + FRESCAN_ERROR("could not set repl thread prio %d\n", FRESCAN_REPL_THREAD_PRIO); return ret; } @@ -245,13 +244,13 @@ int frescan_replenishments_init(frescan_network_t net) frescan_repl_thread, (void *)(uint32_t)net); if (ret != 0) { - ERROR("could not create the replenishment thread\n"); + FRESCAN_ERROR("could not create the replenishment thread\n"); return ret; } ret = fosa_thread_attr_destroy(&attr); if (ret != 0) { - ERROR("could not destroy thread attributes\n"); + FRESCAN_ERROR("could not destroy thread attributes\n"); return ret; } @@ -292,7 +291,7 @@ int frescan_replenishment_program(frescan_network_t net, // move to tail with new repl value repl->when = *timestamp; - incr_timespec (&repl->when, &server->params.values.period); + incr_timespec(repl->when, server->params.period); repl->amount = 1; list_add_tail(&repl->repl_list, @@ -306,7 +305,7 @@ int frescan_replenishment_program(frescan_network_t net, clock_gettime (CLOCK_MONOTONIC, &now); - if (smaller_timespec(&now, &repl->when)) { + if (smaller_timespec(now, repl->when)) { server->current_priority = FRESCAN_BACKGROUND_PRIO; timerdata.it_interval.tv_sec = 0; @@ -320,7 +319,7 @@ int frescan_replenishment_program(frescan_network_t net, ret = timer_settime(server->repl_timer, TIMER_ABSTIME, &timerdata, NULL); if (ret != 0) { - ERROR("could not set the replenishment timer\n"); + FRESCAN_ERROR("could not set the replenishment timer\n"); return ret; } } -- 2.39.2