]> rtime.felk.cvut.cz Git - frescor/fna.git/blobdiff - src_frescan/frescan_servers.c
config values
[frescor/fna.git] / src_frescan / frescan_servers.c
index 861cef0b18cd6a17976cbbacf3ef9f9100ca5165..8f8d3bfc100e0fc0049caeef23a43c2b69354d7d 100644 (file)
@@ -71,6 +71,7 @@
 #include "frescan_servers.h"
 #include "frescan_servers_replenishments.h" // frescan_replenishments_xxx
 #include "frescan_debug.h"
+#include "frescan_packets.h"
 #include "frescan_data.h"
 #include <signal.h>
 #include <time.h>
@@ -89,11 +90,11 @@ int frescan_servers_init(frescan_network_t net)
 
         DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "initializing servers\n");
 
-        ret = freelist_init(&the_servers_pool_freelist[net], FRESCAN_MX_IDS);
+        ret = freelist_init(&frescan_data[net].ss_id_freelist, FRESCAN_MX_IDS);
         if (ret != 0) return ret;
 
         for (i=0; i<FRESCAN_MX_NETWORKS; i++) {
-                INIT_LIST_HEAD(&the_active_servers[net].servers_list);
+                INIT_LIST_HEAD(&frescan_data[net].ss_active_head.servers_list);
         }
 
         ret = frescan_replenishments_init(net);
@@ -120,12 +121,12 @@ int frescan_servers_create(frescan_network_t net,
 {
         int i, ret, pos;
         struct sigevent evp;
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
         frescan_repl_op_t *repl;
 
-        FRESCAN_ACQUIRE_LOCK(&the_networks[net].lock);
-        pos = freelist_alloc(&the_servers_pool_freelist[net]);
-        FRESCAN_RELEASE_LOCK(&the_networks[net].lock);
+        FRESCAN_ACQUIRE_LOCK(&frescan_data[net].lock);
+        pos = freelist_alloc(&frescan_data[net].ss_id_freelist);
+        FRESCAN_RELEASE_LOCK(&frescan_data[net].lock);
 
         if (pos == -1) {
                 FRESCAN_ERROR("could not allocate servers\n");
@@ -134,14 +135,14 @@ int frescan_servers_create(frescan_network_t net,
 
         *id = (frescan_ss_t)pos;
 
-        server = &the_servers_pool[net][*id];
+        server = &frescan_data[net].ss_data[*id];
 
         server->net = net;
         server->id  = *id;
-        server->params = *params;
-        server->current_budget = params->budget;
+        server->committed_params = *params;
+        server->perceived_params = server->committed_params;
         server->current_priority = params->prio;
-        server->pending_packets = 0;
+        server->pending_packets  = 0;
 
         // the first act_time is set to the server creation time
         clock_gettime (CLOCK_MONOTONIC, &server->act_time);
@@ -172,7 +173,8 @@ int frescan_servers_create(frescan_network_t net,
 
         DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG,
               "server created, id:%u budget:%u prio:%u\n",
-              *id, server->params.budget, server->params.prio);
+              *id, server->committed_params.budget,
+              server->committed_params.prio);
 
         return 0;
 }
@@ -190,15 +192,16 @@ int frescan_servers_set_perceived(frescan_network_t net,
                                   const frescan_server_params_t *params,
                                   frescan_ss_t id)
 {
-        the_servers_pool[net][id].params = *params;
+        frescan_data[net].ss_data[id].perceived_params = *params;
         return 0;
 }
 
 /**
  * frescan_servers_commit_perceived() - commit sporadic server perceived data
  *
+ * Add or remove repl operations according to the budget change
+ *
  * @net: the network instance
- * @params: the parameters for the server
  * @id: the identificator for the server
  *
  */
@@ -206,24 +209,45 @@ int frescan_servers_set_perceived(frescan_network_t net,
 int frescan_servers_commit_perceived(frescan_network_t net,
                                      frescan_ss_t id)
 {
+        int i, ret;
+        frescan_ss_data_t *server;
+        int budget_variation;
+        frescan_repl_op_t *repl = NULL;
+        struct list_head *pos;
+
+        server = &frescan_data[net].ss_data[id];
+        budget_variation = server->perceived_params.budget -
+                           server->committed_params.budget;
+
+        if (budget_variation > 0) {
+                // we have more budget: add repl ops to the tail
+                for (i=0; i < budget_variation; i++) {
+                        repl = frescan_repl_op_alloc();
+                        repl->when = server->act_time; // TODO: check when!
+                        repl->amount = 1;
+                        list_add_tail(&repl->repl_list,
+                                      &server->replenishments.repl_list);
+                }
+        } else {
+                // we have less budget: remove repl ops from the tail
+                for (i=0; i > budget_variation; i--) {
+                        list_for_each_prev(pos,
+                                           &server->replenishments.repl_list) {
+                                repl = list_entry(pos,
+                                                  frescan_repl_op_t,
+                                                  repl_list);
+                                break;
+                        }
+                        list_del(&repl->repl_list);
+
+                        ret = frescan_repl_op_free(repl);
+                        if (ret != 0) return ret;
+                }
+        }
+
+        server->committed_params = server->perceived_params;
 
-//         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_server_data_t;
-
-        // TODO: remove or add replenishment operations
-        ...
-        return -1;
+        return 0;
 }
 
 /**
@@ -261,21 +285,44 @@ int frescan_servers_update(frescan_network_t net,
 int frescan_servers_destroy(frescan_network_t net, frescan_ss_t id)
 {
         int ret;
+        frescan_repl_op_t *repl;
+        frescan_packet_t *packet;
+        frescan_ss_data_t *server;
 
-        // TODO: free the replenishment operations and the packets for the
-        // server.
+        server = &frescan_data[net].ss_data[id];
 
-        ret = timer_delete (the_servers_pool[net][id].repl_timer);
+        ret = timer_delete (server->repl_timer);
         if (ret != 0) {
                 FRESCAN_ERROR("could not delete timer\n");
                 return ret;
         }
 
-        FRESCAN_ACQUIRE_LOCK(&the_networks[net].lock);
-        list_del(&the_servers_pool[net][id].servers_list);
+        // remove packets associated to the server
+        if (!list_empty(&server->packet_list.fifo_list)) {
+                FRESCAN_WARNING("destroying a server with packets enqueued\n");
+                list_for_each_entry(packet,
+                                    &server->packet_list.fifo_list,
+                                    fifo_list) {
+                        ret = frescan_packets_free(packet);
+                        if (ret != 0) return ret;
+                }
+                INIT_LIST_HEAD(&server->packet_list.fifo_list);
+        }
+
+        // remove the servers replenishment capacity queue
+        list_for_each_entry(repl,
+                            &server->replenishments.repl_list,
+                            repl_list) {
+                ret = frescan_repl_op_free(repl);
+                if (ret != 0) return ret;
+        }
+        INIT_LIST_HEAD(&server->replenishments.repl_list);
+
+        FRESCAN_ACQUIRE_LOCK(&frescan_data[net].lock);
+        list_del(&server->servers_list);
+        ret = freelist_free(&frescan_data[net].ss_id_freelist, id);
+        FRESCAN_RELEASE_LOCK(&frescan_data[net].lock);
 
-        ret = freelist_free(&the_servers_pool_freelist[net], id);
-        FRESCAN_RELEASE_LOCK(&the_networks[net].lock);
         if (ret != 0) {
                 FRESCAN_ERROR("could not free server data from pool\n");
                 return ret;
@@ -297,24 +344,58 @@ int frescan_servers_get_data(frescan_network_t net,
                              frescan_server_params_t *params,
                              frescan_ss_t id)
 {
-        *params = the_servers_pool[net][id].params;
+        *params = frescan_data[net].ss_data[id].perceived_params;
         return 0;
 }
 
 /**
- * frescan_servers_get_current_budget() - get the current sporadic server budget
+ * frescan_servers_get_current_budget() - get the current ss budget
  *
  * @net: the network instance
  * @id: the identificator for the server
  * @current_budget: the current budget of the server
  *
+ * Traverse the capacity queue until we find a replenishment operation
+ * that was programmed for a time later than now. The number of iterations
+ * is the budget in the capacity queue.
+ *
+ * That budget must be modified if the perceived budget has not been
+ * committed yet.
+ *
  */
 
 int frescan_servers_get_current_budget(frescan_network_t net,
                                        frescan_ss_t id,
                                        frescan_budget_t *current_budget)
 {
-        *current_budget = the_servers_pool[net][id].current_budget;
+        struct timespec now;
+        frescan_repl_op_t *repl;
+        frescan_ss_data_t *server;
+        int count;
+
+        server = &frescan_data[net].ss_data[id];
+
+        // first we get the current real budget in the capacity queue
+        clock_gettime (CLOCK_MONOTONIC, &now);
+
+        count = 0;
+        list_for_each_entry(repl,
+                            &server->replenishments.repl_list,
+                            repl_list) {
+                if (smaller_timespec(now, repl->when)) break;
+                count = count + 1;
+        }
+
+        // if the perceived budget is less than the real budget
+        // we have to give a _perceived_ current budget
+        if (server->perceived_params.budget < server->committed_params.budget) {
+                count = server->perceived_params.budget -
+                        (server->committed_params.budget - count);
+                if (count < 0) count = 0;
+        }
+
+        *current_budget = (frescan_budget_t)count;
+
         return 0;
 }
 
@@ -337,16 +418,17 @@ int frescan_servers_get_highest_prio(frescan_network_t net,
                                      frescan_ss_t *id,
                                      frescan_prio_t *prio)
 {
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
 
-        if (list_empty(&the_active_servers->servers_list)) {
+        if (list_empty(&frescan_data[net].ss_active_head.servers_list)) {
                 DEBUG(FRESCAN_SERVERS_ENABLE_DEBUG, "server list is empty\n");
                 *id = FRESCAN_MX_IDS;
                 return 0;
         }
 
         *prio = 0;
-        list_for_each_entry(server, &the_active_servers[net].servers_list,
+        list_for_each_entry(server,
+                            &frescan_data[net].ss_active_head.servers_list,
                             servers_list) {
                 if (server->current_priority >= *prio) {
                         *id = server->id;
@@ -381,9 +463,9 @@ int frescan_servers_frame_sent(frescan_network_t net,
 {
         int ret;
         struct timespec *repl_time;
-        frescan_server_data_t *server;
+        frescan_ss_data_t *server;
 
-        server = &the_servers_pool[net][id];
+        server = &frescan_data[net].ss_data[id];
 
         if (server->current_priority != FRESCAN_BACKGROUND_PRIO) {
                 if (smaller_timespec(packet->timestamp, server->act_time)) {
@@ -391,6 +473,7 @@ int frescan_servers_frame_sent(frescan_network_t net,
                 } else {
                         repl_time = &packet->timestamp;
                 }
+
                 ret = frescan_replenishment_program(net, id, repl_time);
                 if (ret != 0) return -1;
         }