the new formulation including feasibility constraints
[oweals/gnunet.git] / src / transport / gnunet-service-transport.c
index ba9cdfbc6ee24d97d2843400f5f53993b0f76a14..839e3fd38f7034a22dd132eabd6efa39c6680578 100644 (file)
 #include "gnunet_signatures.h"
 #include "gnunet_transport_plugin.h"
 #include "transport.h"
-#if HAVE_GLPK
+#if HAVE_LIBGLPK
 #include <glpk.h>
 #endif
 
-#define DEBUG_BLACKLIST GNUNET_YES
+#define DEBUG_BLACKLIST GNUNET_NO
 
-#define DEBUG_PING_PONG GNUNET_YES
+#define DEBUG_PING_PONG GNUNET_NO
 
-#define DEBUG_TRANSPORT_HELLO GNUNET_YES
+#define DEBUG_TRANSPORT_HELLO GNUNET_NO
+
+#define DEBUG_ATS GNUNET_NO
+#define VERBOSE_ATS GNUNET_NO
 
 /**
  * Should we do some additional checks (to validate behavior
@@ -930,27 +933,27 @@ static void disconnect_neighbour (struct NeighbourList *n, int check);
  * Check the ready list for the given neighbour and if a plugin is
  * ready for transmission (and if we have a message), do so!
  *
- * @param neighbour target peer for which to transmit
+ * @param nexi target peer for which to transmit
  */
 static void try_transmission_to_peer (struct NeighbourList *n);
 
 
 struct ATS_info * ats_init ();
 
-void ats_shutdown (struct ATS_info * ats);
+void ats_shutdown ( );
 
-void ats_notify_peer_connect (struct ATS_info * ats,
+void ats_notify_peer_connect (
                const struct GNUNET_PeerIdentity *peer,
                const struct GNUNET_TRANSPORT_ATS_Information *ats_data);
 
-void ats_notify_peer_disconnect (struct ATS_info * ats,
+void ats_notify_peer_disconnect (
                const struct GNUNET_PeerIdentity *peer);
 
-void ats_notify_ats_data (struct ATS_info * ats,
+void ats_notify_ats_data (
                const struct GNUNET_PeerIdentity *peer,
                const struct GNUNET_TRANSPORT_ATS_Information *ats_data);
 
-struct ForeignAddressList * ats_get_preferred_address (struct ATS_info * ats,
+struct ForeignAddressList * ats_get_preferred_address (
                struct NeighbourList *n);
 
 /**
@@ -1675,7 +1678,7 @@ try_transmission_to_peer (struct NeighbourList *n)
   if (mq->specific_address == NULL)
     {
          /* TODO: ADD ATS */
-      mq->specific_address = ats_get_preferred_address(ats, n);
+      mq->specific_address = ats_get_preferred_address(n);
       GNUNET_STATISTICS_update (stats,
                                gettext_noop ("# transport selected peer address freely"),
                                1,
@@ -2310,7 +2313,7 @@ notify_clients_connect (const struct GNUNET_PeerIdentity *peer,
   memcpy (&cim->id, peer, sizeof (struct GNUNET_PeerIdentity));
 
   /* notify ats about connecting peer */
-  ats_notify_peer_connect(ats, peer, &(cim->ats));
+  ats_notify_peer_connect (peer, &(cim->ats));
 
   cpos = clients;
   while (cpos != NULL)
@@ -2347,7 +2350,7 @@ notify_clients_disconnect (const struct GNUNET_PeerIdentity *peer)
   memcpy (&dim.peer, peer, sizeof (struct GNUNET_PeerIdentity));
 
   /* notify ats about connecting peer */
-  ats_notify_peer_disconnect(ats, peer);
+  ats_notify_peer_disconnect (peer);
 
   cpos = clients;
   while (cpos != NULL)
@@ -4822,8 +4825,7 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
          }
   }
   /* notify ATS about incoming data */
-  ats_notify_ats_data(ats, peer, ats_data);
-
+  ats_notify_ats_data(peer, ats_data);
 
   if (message != NULL)
     {
@@ -5549,194 +5551,402 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   GNUNET_break (bc_head == NULL);
 }
 
+struct ATS_mechanism
+{
+       struct ATS_mechanism * prev;
+       struct ATS_mechanism * next;
+       struct ForeignAddressList * addr;
+       struct TransportPlugin * plugin;
+       struct ATS_peer * peer;
+       int col_index;
+       int     id;
+       double c_max;
+       double c_1;
+};
 
+struct ATS_peer
+{
+       int id;
+       struct GNUNET_PeerIdentity peer;
+       struct NeighbourList * n;
+       struct ATS_mechanism * m_head;
+       struct ATS_mechanism * m_tail;
+
+       /* preference value f */
+       double f;
+       int     t;
+};
 
-#if HAVE_GLPK
 
-glp_prob * ats_create_problem(int peers, double b_min, double b_max, double r, const struct ATS_peer * list, int max_it, int max_dur)
+static void ats_create_problem (int max_it, int max_dur )
 {
-       int c1, c2;
-       glp_prob *lp;
-       char * transport;
-
-       int rows = 1 + peers + peers + peers;
-       int cols = peers;
-       int index = 1;
-       int start = 0;
-       int cur_row = 0;
-
-       int ia[1+(rows*cols)], ja[1+(rows*cols)];
-       double ar[1+(rows*cols)];
-       double value;
-
-       /* Setting options */
-/*     glp_smcp * options = GNUNET_malloc( sizeof (glp_smcp));
-       // max iterations
-       options->it_lim = max_it;
-       // max durations
-       options->tm_lim = max_it;
-       options->msg_lev = GLP_MSG_OFF;
-       options->meth = GLP_PRIMAL;
-       options->pricing = GLP_PT_PSE;
-       options->r_test = GLP_RT_HAR;
-       options->tol_bnd =
-*/
+#if !HAVE_LIBGLPK
+       if (DEBUG_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "no glpk installed\n");
+       return;
+#else
+       if (DEBUG_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "glpk installed\n");
+#endif
 
-       lp = glp_create_prob();
-       glp_set_prob_name(lp, "gnunet ats bandwidth distribution");
-       glp_set_obj_dir(lp, GLP_MAX);
+       glp_prob *prob;
 
-       /* Adding transports */
-       glp_add_cols(lp, cols);
-       for (c1=1; c1<=cols; c1++)
-       {
-               GNUNET_asprintf(&transport,"Peer %s",GNUNET_i2s(&list[c1-1].peer));
-               //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats_create_problem Peer[%i] : %s \n",c1-1 , transport);
-               /* add a single transport */
-               glp_set_col_name(lp, c1, transport);
-               /* add a lower bound */
-               glp_set_col_bnds(lp, c1, GLP_LO, 0.0, 0.0);
-               /* set coefficient function */
-               glp_set_obj_coef(lp, c1, 1.0);
-               GNUNET_free(transport);
-       }
+       int c_peers = 0;
+       int c_mechs = 0;
 
+       int c_c_ressources = 0;
+       int c_q_metrics = 0;
 
-       /* Adding constraints */
-       glp_add_rows(lp, rows);
-       cur_row = 1;
+       double v_b_min = 100;
+       double v_n_min = 2;
+       double M = 1000000000;
 
-       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "row: %i \n", cur_row);
-       glp_set_row_bnds(lp, cur_row, GLP_UP, 0.0, b_max);
-       for (index=1; index<=cols; index++)
+       struct NeighbourList *next = neighbours;
+       while (next!=NULL)
        {
-               ia[index] = 1, ja[index] = index, ar[index] = 1.0;
+               struct ReadyList *r_next = next->plugins;
+               while (r_next != NULL)
+               {
+                       struct ForeignAddressList * a_next = r_next->addresses;
+                       while (a_next != NULL)
+                       {
+                               c_mechs++;
+                               a_next = a_next->next;
+                       }
+                       r_next = r_next->next;
+               }
+               next = next->next;
+               c_peers++;
+       }
+
+       if (c_mechs==0)
+       {
+               GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No addresses for bw distribution available\n", c_peers);
+               return;
        }
 
+       struct ATS_mechanism * mechanisms = GNUNET_malloc((1+c_mechs) * sizeof (struct ATS_mechanism));
+       struct ATS_peer * peers = GNUNET_malloc((1+c_peers) * sizeof (struct ATS_peer));
 
-       cur_row = 2;
-       start = index+1;
-       for (c1=0; c1<peers; c1++)
+       if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found mechanisms: %i\n", c_mechs);
+       c_mechs = 1;
+       c_peers = 1;
+       next = neighbours;
+       while (next!=NULL)
        {
-               //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "row: %i \n", cur_row);
-               glp_set_row_bnds(lp, cur_row , GLP_UP, 0.0, b_max);
+               peers[c_peers].peer = next->id;
+               peers[c_peers].m_head = NULL;
+               peers[c_peers].m_tail = NULL;
 
-               for (c2 = 1; c2 <= cols; c2++)
+               struct ReadyList *r_next = next->plugins;
+               while (r_next != NULL)
                {
-                       //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "c1: %i c2 %i  index: %i \n",c1 , c2, index);
-                       ia[index] = cur_row;
-                       ja[index] = c2;
-                       ar[index] = ((c1+1 == c2) ? 1.0 : 0.0);
-                       //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ia: %i ja %i  ar: %f \n",cur_row , c2, ((c1+1 == c2) ? 1.0 : 0.0));
-                       index++;
+                       struct ForeignAddressList * a_next = r_next->addresses;
+                       while (a_next != NULL)
+                       {
+                               if (DEBUG_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%i Peer: `%s' %x:\n", c_mechs, GNUNET_i2s(&next->id),
+                                                                                               a_next);
+                               mechanisms[c_mechs].addr = a_next;
+                               mechanisms[c_mechs].col_index = c_mechs;
+                               mechanisms[c_mechs].peer = &peers[c_peers];
+                               mechanisms[c_mechs].next = NULL;
+
+                               GNUNET_CONTAINER_DLL_insert_tail(peers[c_peers].m_head, peers[c_peers].m_tail, &mechanisms[c_mechs]);
+                               c_mechs++;
+                               a_next = a_next->next;
+                       }
+                       r_next = r_next->next;
                }
-               cur_row++;
+               c_peers++;
+               next = next->next;
        }
+       c_mechs--;
+       c_peers--;
+
+       /* number of variables == coloumns */
+       //int c_cols = 2 * c_mechs + 3 + c_q_metrics;
+       /* number of constraints == rows */
+       //int c_rows = 2 * c_peers + 2 * c_mechs + c_c_ressources + c_q_metrics + 3;
+
+       if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating problem with: %i peers, %i mechanisms\n", c_peers, c_mechs);
+
+       int size = 6 *c_mechs;
+       int row_index;
+       int array_index=0;
+       int * ia = GNUNET_malloc (size * sizeof (int));
+       int * ja = GNUNET_malloc (size * sizeof (int));
+       double * ar = GNUNET_malloc(size* sizeof (double));
+
+       prob = glp_create_prob();
+       glp_set_prob_name(prob, "gnunet ats bandwidth distribution");
+       glp_set_obj_dir(prob, GLP_MAX);
+
+       /* adding columns */
+       int c;
+       char * name;
+       glp_add_cols(prob, 2 * c_mechs);
+       for (c=1; c <= c_mechs; c++)
+       {
+               GNUNET_asprintf(&name, "b%i",c);
+               glp_set_col_name(prob, c, name);
+               GNUNET_free (name);
+               glp_set_col_bnds(prob, c, GLP_LO, 0.0, 0.0);
+               glp_set_obj_coef(prob, c, 1.0);
 
-       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "CONST 3 \n");
+       }
+       for (c=c_mechs; c <= 2*c_mechs; c++)
+       {
+               GNUNET_asprintf(&name, "n%i",c);
+               glp_set_col_name(prob, c, "n1");
+               glp_set_col_bnds(prob, c, GLP_LO, 0.0, 0.0);
+               glp_set_col_bnds(prob, c, GLP_LO, 0.0, 1.0);
+               glp_set_col_kind(prob, c, GLP_IV);
+               glp_set_obj_coef(prob, c, 1.0);
+               GNUNET_free (name);
+       }
 
-       start = index+1;
-       for (c1=0; c1<peers; c1++)
+       /* feasibility constraints */
+       /* one address per peer*/
+       if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Constraint 1\n");
+       row_index = 1;
+       glp_add_rows(prob, c_peers);
+       for (c=1; c<=c_peers; c++)
        {
-               //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "row: %i \n", cur_row);
-               glp_set_row_bnds(lp, cur_row , GLP_LO, b_min, 0.0);
+               glp_set_row_bnds(prob, row_index, GLP_DB, 0.0, 1.0);
 
-               for (c2 = 1; c2 <= cols; c2++)
+               struct ATS_mechanism *m = peers[c].m_head;
+               while (m!=NULL)
                {
-                       //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "c1: %i c2 %i  index: %i \n",c1 , c2, index);
-                       ia[index] = cur_row;
-                       ja[index] = c2;
-                       ar[index] = ((c1+1 == c2) ? 1.0 : 0.0);
-                       //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ia: %i ja %i  ar: %f \n",cur_row , c2, ((c1+1 == c2) ? 1.0 : 0.0));
-                       index++;
+                       ia[array_index] = row_index;
+                       ja[array_index] = (c_mechs + m->col_index);
+                       ar[array_index] = 1;
+                       if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]);
+                       array_index++;
+                       m = m->next;
                }
-               cur_row++;
+               row_index++;
        }
+       GNUNET_assert (row_index-1==c_peers);
+       GNUNET_assert (array_index==c_mechs);
 
-       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "CONST 4 \n");
+       /* Constraint 1: only active mechanism gets bandwidth assigned */
+       if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Constraint 2\n");
+       glp_add_rows(prob, c_mechs);
+       for (c=1; c<=c_mechs; c++)
+       {
+               /* b_t - n_t * M <= 0 */
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
+               glp_set_row_bnds(prob, row_index, GLP_UP, 0.0, 0.0);
+
+               ia[array_index] = row_index;
+               ja[array_index] = mechanisms[c].col_index;
+               ar[array_index] = 1;
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]);
+               array_index++;
+               ia[array_index] = row_index;
+               ja[array_index] = c_mechs + mechanisms[c].col_index;
+               ar[array_index] = -M;
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]);
+               array_index++;
+               row_index ++;
+       }
+       GNUNET_assert (row_index-1==c_peers+c_mechs);
+       GNUNET_assert (array_index==c_mechs+(2*c_mechs));
 
-       start = index+1;
-       for (c1=0; c1<peers; c1++)
+       /* Constraint 3: minimum bandwidth*/
+       if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Constraint 3\n");
+       glp_add_rows(prob, c_mechs);
+       for (c=1; c<=c_mechs; c++)
+       {
+               /* b_t - n_t * b_min <= 0 */
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
+               glp_set_row_bnds(prob, row_index, GLP_UP, 0.0, 0.0);
+
+               ia[array_index] = row_index;
+               ja[array_index] = mechanisms[c].col_index;
+               ar[array_index] = 1;
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]);
+               array_index++;
+               ia[array_index] = row_index;
+               ja[array_index] = c_mechs + mechanisms[c].col_index;
+               ar[array_index] = -v_b_min;
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]);
+               array_index++;
+               row_index ++;
+       }
+       GNUNET_assert (row_index-1==c_peers+(2*c_mechs));
+       GNUNET_assert (array_index==c_mechs+(4*c_mechs));
+
+       /* Constraint 4: max ressource capacity */
+       /*
+       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Constraint 3\n");
+       glp_add_rows(prob, c_mechs);
+       for (c=1; c<=c_mechs; c++)
        {
+               // b_t - n_t * b_min >= 0
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
+               glp_set_row_bnds(prob, row_index, GLP_LO, 0.0, 0.0);
+
+               ia[array_index] = row_index;
+               ja[array_index] = mechanisms[c].col_index;
+               ar[array_index] = 1;
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]);
+               array_index++;
+               ia[array_index] = row_index;
+               ja[array_index] = c_mechs + mechanisms[c].col_index;
+               ar[array_index] = -v_b_min;
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]);
+               array_index++;
+               row_index ++;
+       }
+       GNUNET_assert (row_index-1==c_peers+(2*c_mechs));
+       GNUNET_assert (array_index==5*c_mechs);
+       */
+
+       /* Constraint 5: min number of connections*/
+       if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Constraint 5\n");
+       glp_add_rows(prob, 1);
+       for (c=1; c<=c_mechs; c++)
+       {
+               // b_t - n_t * b_min >= 0
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
+               glp_set_row_bnds(prob, row_index, GLP_LO, v_n_min, 0.0);
+
+               ia[array_index] = row_index;
+               ja[array_index] = c_mechs + mechanisms[c].col_index;
+               ar[array_index] = 1;
+               if (VERBOSE_ATS) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]);
+               array_index++;
+       }
+       row_index ++;
+       GNUNET_assert (row_index-1==c_peers+(2*c_mechs)+1);
+       GNUNET_assert (array_index==6*c_mechs);
 
-               value = list[c1].f * r;
-               GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "row: %i %f\n", cur_row, value);
-               glp_set_row_bnds(lp, cur_row , GLP_LO, value, 0.0);
+       glp_load_matrix(prob, array_index-1, ia, ja, ar);
 
-               for (c2 = 1; c2 <= cols; c2++)
-               {
-                       //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "c1: %i c2 %i  index: %i \n",c1 , c2, index);
-                       ia[index] = cur_row;
-                       ja[index] = c2;
-                       ar[index] = ((c1+1 == c2) ? (1.0/b_max) : 0.0);
-                       //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ia: %i ja %i  ar: %f \n",cur_row , c2, ((c1+1 == c2) ? 1.0 : 0.0));
-                       index++;
-               }
-               cur_row++;
-       }
+       glp_delete_prob(prob);
 
-       glp_load_matrix(lp, rows * cols, ia, ja, ar);
+       /* clean up */
 
-       glp_simplex(lp, NULL);
+       GNUNET_free (ja);
+       GNUNET_free (ia);
+       GNUNET_free (ar);
 
+       GNUNET_free(mechanisms);
+       GNUNET_free(peers);
+}
 
-       printf("z = %g; ", glp_get_obj_val(lp));
-       for (c1=1; c1<= peers; c1++ )
+/* To remove: just for testing */
+void ats_benchmark (int peers, int transports, int start_peers, int end_peers)
+{
+       struct GNUNET_TIME_Absolute start;
+       struct GNUNET_TIME_Relative duration;
+/*
+       int test = 11;
+       int mlp = GNUNET_NO;
+
+       for (test=start_peers; test<=end_peers; test++)
+       {
+       int peers = test;
+       int transports = 3;
+
+       double b_min   = 5;
+       double b_max   = 50;
+       double r           = 0.85;//1.0;
+       double R           = 1.0;
+
+       int it = ATS_MAX_ITERATIONS;
+       int dur = 500;
+       if (INT_MAX < ats->max_exec_duration.rel_value)
+               dur = INT_MAX;
+       else
+               dur = (int) ats->max_exec_duration.rel_value;
+
+
+       struct ATS_mechanism * tl = GNUNET_malloc(transports * sizeof (struct ATS_peer));
+
+       struct ATS_peer * pl = GNUNET_malloc(peers * sizeof (struct ATS_peer));
+       int c = 0;
+       while (c < peers)
        {
-               printf("x%i = %g; ", c1, glp_get_col_prim(lp, c1));
+               pl[c].peer.hashPubKey.bits[0] = c+1;
+               pl[c].f = 1 / (double) peers ;
+               pl[c].t = 1;
+               //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats_calculate_bandwidth_distribution Peer[%i] : %s %p \n",c , GNUNET_i2s(&pl[c].peer), &pl[c].peer);
+               c++;
+       }
+       c = 0;
+       while (c < transports)
+       {
+               tl[c].id = c;
+               tl[c].c_max = 10000;
+               tl[c].c_1 = 1;
+               //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats_calculate_bandwidth_distribution Peer[%i] : %i \n",c , tl[c].id);
+               c++;
+
        }
-       glp_delete_prob(lp);
-       //GNUNET_free(options);
-       return lp;
-}
-#else
-void ats_create_problem(int peers, double b_min, double b_max, double r, const struct ATS_peer * list, int max_it, int max_dur)
-{
 
+       // test //
+
+       //pl[0].f = 0.33;
+       //pl[2].f = 0.43;
+       //pl[1].f = 0.33;
+       // test //
+        *
+        */
+       start = GNUNET_TIME_absolute_get();
+       ats_create_problem(5000,5000);
+
+       duration = GNUNET_TIME_absolute_get_difference(start,GNUNET_TIME_absolute_get());
+
+       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "benchmark result: %llu\n", duration);
+
+       GNUNET_STATISTICS_set (stats, "ATS execution time 100 peers", duration.rel_value, GNUNET_NO);
 }
-#endif
 
-void ats_calculate_bandwidth_distribution (struct ATS_info * ats)
+void ats_calculate_bandwidth_distribution ()
 {
        struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference(ats->last,GNUNET_TIME_absolute_get());
        if (delta.rel_value < ats->min_delta.rel_value)
        {
 #if DEBUG_ATS
-               //GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Minimum time between cycles not reached\n");
+               GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Minimum time between cycles not reached\n");
 #endif
                return;
        }
-#if DEBUG_ATS
-       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "CALCULATE DISTRIBUTION\n");
-#endif
 
-       int transports = 9;
-       double b_min   = 10;
-       double b_max   = 100.0;
-       double r           = 0.8;
+       struct GNUNET_TIME_Absolute start;
+       /*
+       int mlp = GNUNET_NO;
+       int peers;
+       int transports;
 
-       int it = 50;
+       double b_min;
+       double b_max;
+       double r;
+       double R;
+
+       int it = ATS_MAX_ITERATIONS;
+       */
        int dur = 500;
+       if (INT_MAX < ats->max_exec_duration.rel_value)
+               dur = INT_MAX;
+       else
+               dur = (int) ats->max_exec_duration.rel_value;
 
-       struct ATS_peer * list = GNUNET_malloc(transports * sizeof (struct ATS_peer));
-       int c = 0;
-       while (c < transports)
-       {
-               list[c].peer.hashPubKey.bits[0] = c+1;
-               list[c].f = 1 / (double) transports;
-               //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats_calculate_bandwidth_distribution Peer[%i] : %s %p \n",c , GNUNET_i2s(&list[c].peer), &list[c].peer);
-               c++;
-       }
+       struct ATS_mechanism * tl = NULL;
+       struct ATS_peer * pl = NULL;
 
-       ats_create_problem(transports, b_min, b_max, r, list, it, dur);
+       start = GNUNET_TIME_absolute_get();
+       ats_benchmark(100,3,100,100);
+       //ats_create_problem(peers, transports, b_min, b_max, r, R, pl, tl, it, dur, mlp);
 
-       GNUNET_free (list);
+       GNUNET_free_non_null (pl);
+       GNUNET_free_non_null (tl);
 
        ats->last = GNUNET_TIME_absolute_get();
-
 }
 
 
+
 void
 ats_schedule_calculation (void *cls,
                          const struct GNUNET_SCHEDULER_TaskContext *tc)
@@ -5754,7 +5964,7 @@ ats_schedule_calculation (void *cls,
 #endif
        ats_calculate_bandwidth_distribution (ats);
 
-       ats->ats_task = GNUNET_SCHEDULER_add_delayed (ats->reg_delta,
+       ats->ats_task = GNUNET_SCHEDULER_add_delayed (ats->exec_intervall,
                                        &ats_schedule_calculation, ats);
 }
 
@@ -5786,7 +5996,9 @@ struct ATS_info * ats_init ()
        GNUNET_assert(ats->peers!=NULL);
 
        ats->min_delta = ATS_MIN_INTERVAL;
-       ats->reg_delta = ATS_EXEC_INTERVAL;
+       ats->exec_intervall = ATS_EXEC_INTERVAL;
+       ats->max_exec_duration = ATS_MAX_EXEC_DURATION;
+       ats->max_iterations = ATS_MAX_ITERATIONS;
 
        ats->ats_task = GNUNET_SCHEDULER_NO_TASK;
 /*
@@ -5802,7 +6014,7 @@ struct ATS_info * ats_init ()
 }
 
 
-void ats_shutdown (struct ATS_info * ats)
+void ats_shutdown ()
 {
 #if DEBUG_ATS
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats_destroy\n");
@@ -5817,7 +6029,7 @@ void ats_shutdown (struct ATS_info * ats)
 }
 
 
-void ats_notify_peer_connect (struct ATS_info * ats,
+void ats_notify_peer_connect (
                const struct GNUNET_PeerIdentity *peer,
                const struct GNUNET_TRANSPORT_ATS_Information *ats_data)
 {
@@ -5844,7 +6056,7 @@ void ats_notify_peer_connect (struct ATS_info * ats,
        ats_calculate_bandwidth_distribution(ats);
 }
 
-void ats_notify_peer_disconnect (struct ATS_info * ats,
+void ats_notify_peer_disconnect (
                const struct GNUNET_PeerIdentity *peer)
 {
 #if DEBUG_ATS
@@ -5861,7 +6073,7 @@ void ats_notify_peer_disconnect (struct ATS_info * ats,
 }
 
 
-void ats_notify_ats_data (struct ATS_info * ats,
+void ats_notify_ats_data (
                const struct GNUNET_PeerIdentity *peer,
                const struct GNUNET_TRANSPORT_ATS_Information *ats_data)
 {
@@ -5871,17 +6083,17 @@ void ats_notify_ats_data (struct ATS_info * ats,
        ats_calculate_bandwidth_distribution(ats);
 }
 
-struct ForeignAddressList * ats_get_preferred_address (struct ATS_info * ats,
+struct ForeignAddressList * ats_get_preferred_address (
                struct NeighbourList *n)
 {
 #if DEBUG_ATS
-       GNUNET_log (GNUNET_ERROR_TYPE_BULK, "ats_get_prefered_transport for peer: %s\n",GNUNET_i2s(&n->id));
+       //GNUNET_log (GNUNET_ERROR_TYPE_BULK, "ats_get_prefered_transport for peer: %s\n",GNUNET_i2s(&n->id));
 #endif
        struct ReadyList *next = n->plugins;
        while (next != NULL)
        {
 #if DEBUG_ATS
-               GNUNET_log (GNUNET_ERROR_TYPE_BULK, "plugin: %s %i\n",next->plugin->short_name,strcmp(next->plugin->short_name,"unix"));
+               //GNUNET_log (GNUNET_ERROR_TYPE_BULK, "plugin: %s %i\n",next->plugin->short_name,strcmp(next->plugin->short_name,"unix"));
 #endif
                next = next->next;
        }
@@ -5953,11 +6165,6 @@ run (void *cls,
       validation_map = NULL;
       return;
     }
-#if HAVE_GLPK
-         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("HAVE\n"));
-#else
-         //GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("NOT HAVE\n"));
-#endif
 
   ats = ats_init();
   max_connect_per_transport = (uint32_t) tneigh;