]> rtime.felk.cvut.cz Git - frescor/fna.git/blobdiff - src_frescan/frescan_servers.c
changes in frescan, programming the changes of mode and the reservation commit mechan...
[frescor/fna.git] / src_frescan / frescan_servers.c
index c133ee4b12da7e6636a6a127d998d0086b152cb1..5f151b3d1bc6a0b82194159c2f5dbc923de537fd 100644 (file)
@@ -139,7 +139,6 @@ int frescan_servers_create(frescan_network_t net,
         server->net = net;
         server->id  = *id;
         server->params = *params;
-        server->current_budget = params->budget;
         server->current_priority = params->prio;
         server->pending_packets = 0;
 
@@ -177,6 +176,80 @@ int frescan_servers_create(frescan_network_t net,
         return 0;
 }
 
+/**
+ * frescan_servers_set_perceived() - update a sporadic server perceived data
+ *
+ * @net: the network instance
+ * @params: the parameters for the server
+ * @id: the identificator for the server
+ *
+ */
+
+int frescan_servers_set_perceived(frescan_network_t net,
+                                  const frescan_server_params_t *params,
+                                  frescan_ss_t id)
+{
+        frescan_server_data_t *server;
+
+        server = &the_servers_pool[net][id];
+
+        server->old_params = server->params;
+        server->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
+ * @id: the identificator for the server
+ *
+ */
+
+int frescan_servers_commit_perceived(frescan_network_t net,
+                                     frescan_ss_t id)
+{
+        int i, ret;
+        frescan_server_data_t *server;
+        int budget_variation;
+        frescan_repl_op_t *repl;
+        struct list_head *pos;
+
+        server = &the_servers_pool[net][id];
+        budget_variation = server->params.budget - server->old_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;
+                }
+        }
+
+        return 0;
+}
+
 /**
  * frescan_servers_update() - update a sporadic server data
  *
@@ -190,7 +263,14 @@ int frescan_servers_update(frescan_network_t net,
                            const frescan_server_params_t *params,
                            frescan_ss_t id)
 {
-        the_servers_pool[net][id].params = *params;
+        int ret;
+
+        ret = frescan_servers_set_perceived(net, params, id);
+        if (ret != 0) return ret;
+
+        ret = frescan_servers_commit_perceived(net, id);
+        if (ret != 0) return ret;
+
         return 0;
 }
 
@@ -205,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_server_data_t *server;
 
-        // TODO: free the replenishment operations and the packets for the
-        // server.
+        server = &the_servers_pool[net][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(&the_networks[net].lock);
+        list_del(&server->servers_list);
         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;
@@ -246,19 +349,38 @@ int frescan_servers_get_data(frescan_network_t net,
 }
 
 /**
- * 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.
+ *
  */
 
 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_server_data_t *server;
+
+        server = &the_servers_pool[net][id];
+
+        clock_gettime (CLOCK_MONOTONIC, &now);
+
+        *current_budget = 0;
+
+        list_for_each_entry(repl,
+                            &server->replenishments.repl_list,
+                            repl_list) {
+                if (smaller_timespec(now, repl->when)) break;
+                *current_budget = *current_budget + 1;
+        }
+
         return 0;
 }
 
@@ -335,6 +457,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;
         }