aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/testbed/standard_deviation.c129
-rw-r--r--src/testbed/test_testbed_api.conf2
-rw-r--r--src/testbed/testbed_api.c330
-rw-r--r--src/testbed/testbed_api.h62
-rw-r--r--src/testbed/testbed_api_peers.c19
-rw-r--r--src/testbed/testbed_api_peers.h29
6 files changed, 481 insertions, 90 deletions
diff --git a/src/testbed/standard_deviation.c b/src/testbed/standard_deviation.c
index 362b50b26..4bdd6cef2 100644
--- a/src/testbed/standard_deviation.c
+++ b/src/testbed/standard_deviation.c
@@ -18,12 +18,41 @@
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19 */ 19 */
20 20
21#include <gnunet/platform.h> 21#include "platform.h"
22#include <gnunet/gnunet_common.h> 22#include "gnunet_util_lib.h"
23
24struct SDEntry
25{
26 /**
27 * DLL next pointer
28 */
29 struct SDEntry *next;
30
31 /**
32 * DLL prev pointer
33 */
34 struct SDEntry *prev;
35
36 /**
37 * The value to store
38 */
39 unsigned int amount;
40};
41
23 42
24struct SDHandle 43struct SDHandle
25{ 44{
26 /** 45 /**
46 * DLL head for storing entries
47 */
48 struct SDEntry *head;
49
50 /**
51 * DLL tail for storing entries
52 */
53 struct SDEntry *tail;
54
55 /**
27 * Squared sum of data values 56 * Squared sum of data values
28 */ 57 */
29 unsigned long long sqsum; 58 unsigned long long sqsum;
@@ -36,43 +65,78 @@ struct SDHandle
36 /** 65 /**
37 * The average of data amounts 66 * The average of data amounts
38 */ 67 */
39 unsigned int avg; 68 float avg;
40 69
41 /** 70 /**
42 * The variance 71 * The variance
43 */ 72 */
44 unsigned int vr; 73 double vr;
45 74
46 /** 75 /**
47 * Number of data values 76 * Number of data values; also the length of DLL containing SDEntries
48 */ 77 */
49 unsigned int cnt; 78 unsigned int cnt;
79
80 /**
81 * max number of entries we can have in the DLL
82 */
83 unsigned int max_cnt;
50}; 84};
51 85
52 86
53struct SDHandle * 87struct SDHandle *
54GNUNET_TESTBED_SD_init () 88SD_init (unsigned int max_cnt)
55{ 89{
56 return GNUNET_malloc (sizeof (struct SDHandle)); 90 struct SDHandle *h;
91
92 GNUNET_assert (1 < max_cnt);
93 h = GNUNET_malloc (sizeof (struct SDHandle));
94 h->max_cnt = max_cnt;
95 return h;
57} 96}
58 97
59void 98void
60GNUNET_TESTBED_SD_destroy (struct SDHandle *h) 99SD_destroy (struct SDHandle *h)
61{ 100{
101 struct SDEntry *entry;
102
103 while (NULL != (entry = h->head))
104 {
105 GNUNET_CONTAINER_DLL_remove (h->head, h->tail, entry);
106 GNUNET_free (entry);
107 }
62 GNUNET_free (h); 108 GNUNET_free (h);
63} 109}
64 110
65void 111void
66GNUNET_TESTBED_SD_add_data (struct SDHandle *h, unsigned int amount) 112SD_add_data (struct SDHandle *h, unsigned int amount)
67{ 113{
68 unsigned long sqavg; 114 struct SDEntry *entry;
69 115 double sqavg;
116 double sqsum_avg;
117
118 entry = NULL;
119 if (h->cnt == h->max_cnt)
120 {
121 entry = h->head;
122 GNUNET_CONTAINER_DLL_remove (h->head, h->tail, entry);
123 h->sum -= entry->amount;
124 h->sqsum -= ((unsigned long) entry->amount) *
125 ((unsigned long) entry->amount);
126 h->cnt--;
127 }
128 GNUNET_assert (h->cnt < h->max_cnt);
129 if (NULL == entry)
130 entry = GNUNET_malloc (sizeof (struct SDEntry));
131 entry->amount = amount;
132 GNUNET_CONTAINER_DLL_insert_tail (h->head, h->tail, entry);
70 h->sum += amount; 133 h->sum += amount;
71 h->cnt++; 134 h->cnt++;
135 h->avg = ((float) h->sum) / ((float) h->cnt);
72 h->sqsum += ((unsigned long) amount) * ((unsigned long) amount); 136 h->sqsum += ((unsigned long) amount) * ((unsigned long) amount);
73 h->avg = h->sum / h->cnt; 137 sqsum_avg = ((double) h->sqsum) / ((double) h->cnt);
74 sqavg = h->avg * h->avg; 138 sqavg = ((double) h->avg) * ((double) h->avg);
75 h->vr = (h->sqsum / h->cnt) - sqavg; 139 h->vr = sqsum_avg - sqavg;
76} 140}
77 141
78 142
@@ -82,23 +146,24 @@ GNUNET_TESTBED_SD_add_data (struct SDHandle *h, unsigned int amount)
82 * @param h the SDhandle 146 * @param h the SDhandle
83 * @param amount the value for which the deviation is returned 147 * @param amount the value for which the deviation is returned
84 * @return the deviation from the average; GNUNET_SYSERR if the deviation cannot 148 * @return the deviation from the average; GNUNET_SYSERR if the deviation cannot
85 * be calculated 149 * be calculated; a maximum of 4 is returned for deviations equal to
150 * or larger than 4
86 */ 151 */
87int 152int
88GNUNET_TESTBED_SD_deviation_factor (struct SDHandle *h, unsigned int amount) 153SD_deviation_factor (struct SDHandle *h, unsigned int amount)
89{ 154{
90 unsigned long diff; 155 double diff;
91 unsigned int n; 156 unsigned int n;
92 157
93 if (h->cnt < 2) 158 if (h->cnt < 2)
94 return GNUNET_SYSERR; 159 return GNUNET_SYSERR;
95 if (amount > h->avg) 160 if (((float) amount) > h->avg)
96 diff = amount - h->avg; 161 diff = ((float) amount) - h->avg;
97 else 162 else
98 diff = h->avg - amount; 163 diff = h->avg - ((float) amount);
99 diff *= diff; 164 diff *= diff;
100 for (n = 1; n < 4; n++) 165 for (n = 1; n < 4; n++)
101 if (diff < (n * n * h->vr)) 166 if (diff < (((double) (n * n)) * h->vr))
102 break; 167 break;
103 return n; 168 return n;
104} 169}
@@ -107,17 +172,17 @@ GNUNET_TESTBED_SD_deviation_factor (struct SDHandle *h, unsigned int amount)
107int 172int
108main () 173main ()
109{ 174{
110 struct SDHandle * h = GNUNET_TESTBED_SD_init (); 175 struct SDHandle * h = SD_init (20);
111 176
112 GNUNET_TESTBED_SD_add_data (h, 40); 177 SD_add_data (h, 40);
113 GNUNET_TESTBED_SD_add_data (h, 30); 178 SD_add_data (h, 30);
114 GNUNET_TESTBED_SD_add_data (h, 40); 179 SD_add_data (h, 40);
115 GNUNET_TESTBED_SD_add_data (h, 10); 180 SD_add_data (h, 10);
116 GNUNET_TESTBED_SD_add_data (h, 30); 181 SD_add_data (h, 30);
117 printf ("Average: %d\n", h->avg); 182 printf ("Average: %f\n", h->avg);
118 printf ("Variance: %d\n", h->vr); 183 printf ("Variance: %f\n", h->vr);
119 printf ("Standard Deviation: %d\n", (int) sqrt (h->vr)); 184 printf ("Standard Deviation: %f\n", sqrt (h->vr));
120 printf ("Deviation factor: %d\n", GNUNET_TESTBED_SD_deviation (h, 40)); 185 printf ("Deviation factor: %d\n", SD_deviation_factor (h, 60));
121 GNUNET_TESTBED_SD_destroy (h); 186 SD_destroy (h);
122 return 0; 187 return 0;
123} 188}
diff --git a/src/testbed/test_testbed_api.conf b/src/testbed/test_testbed_api.conf
index 880a2d046..9a5252959 100644
--- a/src/testbed/test_testbed_api.conf
+++ b/src/testbed/test_testbed_api.conf
@@ -82,3 +82,5 @@ AUTOSTART = NO
82[consensus] 82[consensus]
83AUTOSTART = NO 83AUTOSTART = NO
84 84
85[gns]
86AUTOSTART = NO \ No newline at end of file
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c
index 2196c826b..eb98bea46 100644
--- a/src/testbed/testbed_api.c
+++ b/src/testbed/testbed_api.c
@@ -248,6 +248,167 @@ struct ControllerLinkData
248}; 248};
249 249
250 250
251struct SDEntry
252{
253 /**
254 * DLL next pointer
255 */
256 struct SDEntry *next;
257
258 /**
259 * DLL prev pointer
260 */
261 struct SDEntry *prev;
262
263 /**
264 * The value to store
265 */
266 unsigned int amount;
267};
268
269
270struct SDHandle
271{
272 /**
273 * DLL head for storing entries
274 */
275 struct SDEntry *head;
276
277 /**
278 * DLL tail for storing entries
279 */
280 struct SDEntry *tail;
281
282 /**
283 * Squared sum of data values
284 */
285 unsigned long long sqsum;
286
287 /**
288 * Sum of the data values
289 */
290 unsigned long sum;
291
292 /**
293 * The average of data amounts
294 */
295 float avg;
296
297 /**
298 * The variance
299 */
300 double vr;
301
302 /**
303 * Number of data values; also the length of DLL containing SDEntries
304 */
305 unsigned int cnt;
306
307 /**
308 * max number of entries we can have in the DLL
309 */
310 unsigned int max_cnt;
311};
312
313
314/**
315 * FIXME: doc
316 *
317 * @param
318 * @return
319 */
320static struct SDHandle *
321SD_init (unsigned int max_cnt)
322{
323 struct SDHandle *h;
324
325 GNUNET_assert (1 < max_cnt);
326 h = GNUNET_malloc (sizeof (struct SDHandle));
327 h->max_cnt = max_cnt;
328 return h;
329}
330
331
332/**
333 * FIXME: doc
334 *
335 * @param
336 * @return
337 */
338static void
339SD_destroy (struct SDHandle *h)
340{
341 struct SDEntry *entry;
342
343 while (NULL != (entry = h->head))
344 {
345 GNUNET_CONTAINER_DLL_remove (h->head, h->tail, entry);
346 GNUNET_free (entry);
347 }
348 GNUNET_free (h);
349}
350
351static void
352SD_add_data (struct SDHandle *h, unsigned int amount)
353{
354 struct SDEntry *entry;
355 double sqavg;
356 double sqsum_avg;
357
358 entry = NULL;
359 if (h->cnt == h->max_cnt)
360 {
361 entry = h->head;
362 GNUNET_CONTAINER_DLL_remove (h->head, h->tail, entry);
363 h->sum -= entry->amount;
364 h->sqsum -= ((unsigned long) entry->amount) *
365 ((unsigned long) entry->amount);
366 h->cnt--;
367 }
368 GNUNET_assert (h->cnt < h->max_cnt);
369 if (NULL == entry)
370 entry = GNUNET_malloc (sizeof (struct SDEntry));
371 entry->amount = amount;
372 GNUNET_CONTAINER_DLL_insert_tail (h->head, h->tail, entry);
373 h->sum += amount;
374 h->cnt++;
375 h->avg = ((float) h->sum) / ((float) h->cnt);
376 h->sqsum += ((unsigned long) amount) * ((unsigned long) amount);
377 sqsum_avg = ((double) h->sqsum) / ((double) h->cnt);
378 sqavg = ((double) h->avg) * ((double) h->avg);
379 h->vr = sqsum_avg - sqavg;
380}
381
382
383/**
384 * Returns the factor by which the given amount differs from the standard deviation
385 *
386 * @param h the SDhandle
387 * @param amount the value for which the deviation is returned
388 * @return the deviation from the average; GNUNET_SYSERR if the deviation cannot
389 * be calculated; a maximum of 4 is returned for deviations equal to
390 * or larger than 4
391 */
392static int
393SD_deviation_factor (struct SDHandle *h, unsigned int amount)
394{
395 double diff;
396 unsigned int n;
397
398 if (h->cnt < 2)
399 return GNUNET_SYSERR;
400 if (((float) amount) > h->avg)
401 diff = ((float) amount) - h->avg;
402 else
403 return 0; //diff = h->avg - ((float) amount);
404 diff *= diff;
405 for (n = 1; n < 4; n++)
406 if (diff < (((double) (n * n)) * h->vr))
407 break;
408 return n;
409}
410
411
251/** 412/**
252 * Returns the operation context with the given id if found in the Operation 413 * Returns the operation context with the given id if found in the Operation
253 * context queues of the controller 414 * context queues of the controller
@@ -604,14 +765,7 @@ handle_peer_conevent (struct GNUNET_TESTBED_Controller *c,
604 cb_cls = data->cb_cls; 765 cb_cls = data->cb_cls;
605 GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc); 766 GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
606 opc->state = OPC_STATE_FINISHED; 767 opc->state = OPC_STATE_FINISHED;
607 GNUNET_free (data); 768 //GNUNET_free (data);
608 /* Increase parallel overlay connects */
609 if (c->num_parallel_connects < c->num_parallel_connects_threshold)
610 c->num_parallel_connects *= 2;
611 else
612 c->num_parallel_connects++;
613 GNUNET_TESTBED_operation_queue_reset_max_active_
614 (c->opq_parallel_overlay_connect_operations, c->num_parallel_connects);
615 if (0 != 769 if (0 !=
616 ((GNUNET_TESTBED_ET_CONNECT | GNUNET_TESTBED_ET_DISCONNECT) & 770 ((GNUNET_TESTBED_ET_CONNECT | GNUNET_TESTBED_ET_DISCONNECT) &
617 c->event_mask)) 771 c->event_mask))
@@ -739,16 +893,6 @@ handle_op_fail_event (struct GNUNET_TESTBED_Controller *c,
739 GNUNET_free (data); 893 GNUNET_free (data);
740 return GNUNET_YES; /* We do not call controller callback for peer info */ 894 return GNUNET_YES; /* We do not call controller callback for peer info */
741 } 895 }
742 if (OP_OVERLAY_CONNECT == opc->type)
743 {
744 /* Decrease the number of parallel overlay connects */
745 c->num_parallel_connects /= 2;
746 c->num_parallel_connects_threshold = c->num_parallel_connects;
747 if (0 == c->num_parallel_connects)
748 c->num_parallel_connects++;
749 GNUNET_TESTBED_operation_queue_reset_max_active_
750 (c->opq_parallel_overlay_connect_operations, c->num_parallel_connects);
751 }
752 if ((0 != (GNUNET_TESTBED_ET_OPERATION_FINISHED & c->event_mask)) && 896 if ((0 != (GNUNET_TESTBED_ET_OPERATION_FINISHED & c->event_mask)) &&
753 (NULL != c->cc)) 897 (NULL != c->cc))
754 { 898 {
@@ -1320,6 +1464,27 @@ oprelease_get_slave_config (void *cls)
1320 1464
1321 1465
1322/** 1466/**
1467 * FIXME: doc
1468 *
1469 * @param
1470 * @return
1471 */
1472static void
1473GNUNET_TESTBED_set_num_parallel_overlay_connects_ (struct
1474 GNUNET_TESTBED_Controller *c,
1475 unsigned int npoc)
1476{
1477 fprintf (stderr, "%d", npoc);
1478 GNUNET_free_non_null (c->tslots);
1479 c->tslots_filled = 0;
1480 c->num_parallel_connects = npoc;
1481 c->tslots = GNUNET_malloc (npoc * sizeof (struct TimeSlot));
1482 GNUNET_TESTBED_operation_queue_reset_max_active_
1483 (c->opq_parallel_overlay_connect_operations, npoc);
1484}
1485
1486
1487/**
1323 * Function to copy NULL terminated list of arguments 1488 * Function to copy NULL terminated list of arguments
1324 * 1489 *
1325 * @param argv the NULL terminated list of arguments. Cannot be NULL. 1490 * @param argv the NULL terminated list of arguments. Cannot be NULL.
@@ -1522,7 +1687,6 @@ GNUNET_TESTBED_controller_connect (const struct GNUNET_CONFIGURATION_Handle
1522 unsigned long long max_parallel_operations; 1687 unsigned long long max_parallel_operations;
1523 unsigned long long max_parallel_service_connections; 1688 unsigned long long max_parallel_service_connections;
1524 unsigned long long max_parallel_topology_config_operations; 1689 unsigned long long max_parallel_topology_config_operations;
1525 unsigned long long num_parallel_connects_threshold;
1526 1690
1527 if (GNUNET_OK != 1691 if (GNUNET_OK !=
1528 GNUNET_CONFIGURATION_get_value_number (cfg, "testbed", 1692 GNUNET_CONFIGURATION_get_value_number (cfg, "testbed",
@@ -1548,11 +1712,6 @@ GNUNET_TESTBED_controller_connect (const struct GNUNET_CONFIGURATION_Handle
1548 GNUNET_break (0); 1712 GNUNET_break (0);
1549 return NULL; 1713 return NULL;
1550 } 1714 }
1551 if (GNUNET_OK !=
1552 GNUNET_CONFIGURATION_get_value_number (cfg, "testbed",
1553 "PARALLEL_OVERLAY_CONNECTS_THRESHOLD",
1554 &num_parallel_connects_threshold))
1555 num_parallel_connects_threshold = 16;
1556 controller = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Controller)); 1715 controller = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Controller));
1557 controller->cc = cc; 1716 controller->cc = cc;
1558 controller->cc_cls = cc_cls; 1717 controller->cc_cls = cc_cls;
@@ -1591,11 +1750,10 @@ GNUNET_TESTBED_controller_connect (const struct GNUNET_CONFIGURATION_Handle
1591 controller->opq_parallel_topology_config_operations= 1750 controller->opq_parallel_topology_config_operations=
1592 GNUNET_TESTBED_operation_queue_create_ ((unsigned int) 1751 GNUNET_TESTBED_operation_queue_create_ ((unsigned int)
1593 max_parallel_topology_config_operations); 1752 max_parallel_topology_config_operations);
1594 controller->num_parallel_connects = 1;
1595 controller->opq_parallel_overlay_connect_operations= 1753 controller->opq_parallel_overlay_connect_operations=
1596 GNUNET_TESTBED_operation_queue_create_ 1754 GNUNET_TESTBED_operation_queue_create_ (0);
1597 (controller->num_parallel_connects); 1755 GNUNET_TESTBED_set_num_parallel_overlay_connects_ (controller, 1);
1598 controller->num_parallel_connects_threshold = num_parallel_connects_threshold; 1756 controller->poc_sd = SD_init (10);
1599 controller_hostname = GNUNET_TESTBED_host_get_hostname (host); 1757 controller_hostname = GNUNET_TESTBED_host_get_hostname (host);
1600 if (NULL == controller_hostname) 1758 if (NULL == controller_hostname)
1601 controller_hostname = "127.0.0.1"; 1759 controller_hostname = "127.0.0.1";
@@ -1688,6 +1846,8 @@ GNUNET_TESTBED_controller_disconnect (struct GNUNET_TESTBED_Controller
1688 (controller->opq_parallel_topology_config_operations); 1846 (controller->opq_parallel_topology_config_operations);
1689 GNUNET_TESTBED_operation_queue_destroy_ 1847 GNUNET_TESTBED_operation_queue_destroy_
1690 (controller->opq_parallel_overlay_connect_operations); 1848 (controller->opq_parallel_overlay_connect_operations);
1849 SD_destroy (controller->poc_sd);
1850 GNUNET_free_non_null (controller->tslots);
1691 GNUNET_free (controller); 1851 GNUNET_free (controller);
1692} 1852}
1693 1853
@@ -2304,4 +2464,118 @@ GNUNET_TESTBED_get_next_op_id (struct GNUNET_TESTBED_Controller *controller)
2304 return op_id; 2464 return op_id;
2305} 2465}
2306 2466
2467
2468/**
2469 * Returns a timing slot which will be exclusively locked
2470 *
2471 * @param c the controller handle
2472 * @return the time slot index in the array of time slots in the controller
2473 * handle
2474 */
2475unsigned int
2476GNUNET_TESTBED_get_tslot_ (struct GNUNET_TESTBED_Controller *c, void *key)
2477{
2478 unsigned int slot;
2479
2480 GNUNET_assert (NULL != c->tslots);
2481 GNUNET_assert (NULL != key);
2482 for (slot = 0; slot < c->num_parallel_connects; slot++)
2483 if (NULL == c->tslots[slot].key)
2484 {
2485 c->tslots[slot].key = key;
2486 return slot;
2487 }
2488 GNUNET_assert (0); /* We should always find a free tslot */
2489}
2490
2491
2492static void
2493decide_npoc (struct GNUNET_TESTBED_Controller *c)
2494{
2495 struct GNUNET_TIME_Relative avg;
2496 int sd;
2497 unsigned int slot;
2498
2499 if (c->tslots_filled != c->num_parallel_connects)
2500 return;
2501 avg = GNUNET_TIME_UNIT_ZERO;
2502 for (slot = 0; slot < c->num_parallel_connects; slot++)
2503 avg = GNUNET_TIME_relative_add (avg, c->tslots[slot].time);
2504 avg = GNUNET_TIME_relative_divide (avg, c->num_parallel_connects);
2505 GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value != avg.rel_value);
2506 sd = SD_deviation_factor (c->poc_sd, (unsigned int) avg.rel_value);
2507 if (GNUNET_SYSERR == sd)
2508 {
2509 SD_add_data (c->poc_sd, (unsigned int) avg.rel_value);
2510 GNUNET_TESTBED_set_num_parallel_overlay_connects_ (c, c->num_parallel_connects);
2511 return;
2512 }
2513 GNUNET_assert (0 <= sd);
2514 if (sd <= 1)
2515 {
2516 SD_add_data (c->poc_sd, (unsigned int) avg.rel_value);
2517 GNUNET_TESTBED_set_num_parallel_overlay_connects_
2518 (c, c->num_parallel_connects * 2);
2519 return;
2520 }
2521 if (1 == c->num_parallel_connects)
2522 {
2523 GNUNET_TESTBED_set_num_parallel_overlay_connects_ (c, 1);
2524 return;
2525 }
2526 GNUNET_TESTBED_set_num_parallel_overlay_connects_
2527 (c, c->num_parallel_connects / 2);
2528}
2529
2530
2531int
2532GNUNET_TESTBED_release_time_slot_ (struct GNUNET_TESTBED_Controller *c,
2533 unsigned int index,
2534 void *key)
2535{
2536 struct TimeSlot *slot;
2537
2538 GNUNET_assert (NULL != key);
2539 if (index >= c->num_parallel_connects)
2540 return GNUNET_NO;
2541 slot = &c->tslots[index];
2542 if (key != slot->key)
2543 return GNUNET_NO;
2544 slot->key = NULL;
2545 return GNUNET_YES;
2546}
2547
2548
2549/**
2550 * Function to update a time slot
2551 *
2552 * @param c the controller handle
2553 * @param index the index of the time slot to update
2554 * @param time the new time
2555 */
2556void
2557GNUNET_TESTBED_update_time_slot_ (struct GNUNET_TESTBED_Controller *c,
2558 unsigned int index,
2559 void *key,
2560 struct GNUNET_TIME_Relative time)
2561{
2562 struct GNUNET_TIME_Relative avg;
2563 struct TimeSlot *slot;
2564
2565 if (GNUNET_NO == GNUNET_TESTBED_release_time_slot_ (c, index, key))
2566 return;
2567 slot = &c->tslots[index];
2568 if (GNUNET_TIME_UNIT_ZERO.rel_value == slot->time.rel_value)
2569 {
2570 slot->time = time;
2571 c->tslots_filled++;
2572 decide_npoc (c);
2573 return;
2574 }
2575 avg = GNUNET_TIME_relative_add (slot->time, time);
2576 avg = GNUNET_TIME_relative_divide (avg, 2);
2577 slot->time = avg;
2578}
2579
2580
2307/* end of testbed_api.c */ 2581/* end of testbed_api.c */
diff --git a/src/testbed/testbed_api.h b/src/testbed/testbed_api.h
index e850fcba2..54a622dbf 100644
--- a/src/testbed/testbed_api.h
+++ b/src/testbed/testbed_api.h
@@ -179,6 +179,30 @@ struct OperationContext
179 179
180 180
181/** 181/**
182 * Opaque handle for SD calculations
183 */
184struct SDHandle;
185
186
187/**
188 * A slot to record time taken by an overlay connect operation
189 */
190struct TimeSlot
191{
192 /**
193 * A key to identify this timeslot
194 */
195 void *key;
196
197 /**
198 * Time
199 */
200 struct GNUNET_TIME_Relative time;
201
202};
203
204
205/**
182 * Handle to interact with a GNUnet testbed controller. Each 206 * Handle to interact with a GNUnet testbed controller. Each
183 * controller has at least one master handle which is created when the 207 * controller has at least one master handle which is created when the
184 * controller is created; this master handle interacts with the 208 * controller is created; this master handle interacts with the
@@ -189,7 +213,6 @@ struct OperationContext
189 */ 213 */
190struct GNUNET_TESTBED_Controller 214struct GNUNET_TESTBED_Controller
191{ 215{
192
193 /** 216 /**
194 * The host where the controller is running 217 * The host where the controller is running
195 */ 218 */
@@ -277,10 +300,22 @@ struct GNUNET_TESTBED_Controller
277 struct OperationQueue *opq_parallel_overlay_connect_operations; 300 struct OperationQueue *opq_parallel_overlay_connect_operations;
278 301
279 /** 302 /**
303 * An array of timing slots; size should be equal to the current number of parallel
304 * overlay connects
305 */
306 struct TimeSlot *tslots;
307
308 /**
309 * Handle for SD calculations amount parallel overlay connect operation finish
310 * times
311 */
312 struct SDHandle *poc_sd;
313
314 /**
280 * The controller event mask 315 * The controller event mask
281 */ 316 */
282 uint64_t event_mask; 317 uint64_t event_mask;
283 318
284 /** 319 /**
285 * Did we start the receive loop yet? 320 * Did we start the receive loop yet?
286 */ 321 */
@@ -297,9 +332,9 @@ struct GNUNET_TESTBED_Controller
297 unsigned int num_parallel_connects; 332 unsigned int num_parallel_connects;
298 333
299 /** 334 /**
300 * The threshold for the number of parallel overlay connects we do 335 * Counter to indicate when all the available time slots are filled
301 */ 336 */
302 unsigned int num_parallel_connects_threshold; 337 unsigned int tslots_filled;
303 338
304 /** 339 /**
305 * The operation id counter. use current value and increment 340 * The operation id counter. use current value and increment
@@ -500,5 +535,24 @@ GNUNET_TESTBED_controller_link_ (void *op_cls,
500 *slave_cfg, 535 *slave_cfg,
501 int is_subordinate); 536 int is_subordinate);
502 537
538unsigned int
539GNUNET_TESTBED_get_tslot_ (struct GNUNET_TESTBED_Controller *c, void *key);
540
541
542void
543GNUNET_TESTBED_update_time_slot_ (struct GNUNET_TESTBED_Controller *c,
544 unsigned int index,
545 void *key,
546 struct GNUNET_TIME_Relative time);
547
548
549int
550GNUNET_TESTBED_release_time_slot_ (struct GNUNET_TESTBED_Controller *c,
551 unsigned int index,
552 void *key);
553
554
555
556
503#endif 557#endif
504/* end of testbed_api.h */ 558/* end of testbed_api.h */
diff --git a/src/testbed/testbed_api_peers.c b/src/testbed/testbed_api_peers.c
index cee50bbff..d558ef06d 100644
--- a/src/testbed/testbed_api_peers.c
+++ b/src/testbed/testbed_api_peers.c
@@ -340,6 +340,8 @@ opstart_overlay_connect (void *cls)
340 opc->state = OPC_STATE_STARTED; 340 opc->state = OPC_STATE_STARTED;
341 data = opc->data; 341 data = opc->data;
342 GNUNET_assert (NULL != data); 342 GNUNET_assert (NULL != data);
343 data->tslot_index = GNUNET_TESTBED_get_tslot_ (opc->c, data);
344 data->tstart = GNUNET_TIME_absolute_get ();
343 msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)); 345 msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage));
344 msg->header.size = 346 msg->header.size =
345 htons (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)); 347 htons (sizeof (struct GNUNET_TESTBED_OverlayConnectMessage));
@@ -362,12 +364,24 @@ static void
362oprelease_overlay_connect (void *cls) 364oprelease_overlay_connect (void *cls)
363{ 365{
364 struct OperationContext *opc = cls; 366 struct OperationContext *opc = cls;
367 struct GNUNET_TIME_Relative duration;
368 struct OverlayConnectData *data;
365 369
366 if (OPC_STATE_STARTED == opc->state) 370 data = opc->data;
371 switch (opc->state)
367 { 372 {
368 GNUNET_free (opc->data); 373 case OPC_STATE_INIT:
374 break;
375 case OPC_STATE_STARTED:
376 (void) GNUNET_TESTBED_release_time_slot_ (opc->c, data->tslot_index, data);
369 GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc); 377 GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
378 break;
379 case OPC_STATE_FINISHED:
380 duration = GNUNET_TIME_absolute_get_duration (data->tstart);
381 GNUNET_TESTBED_update_time_slot_ (opc->c, data->tslot_index,
382 data, duration);
370 } 383 }
384 GNUNET_free (data);
371 GNUNET_free (opc); 385 GNUNET_free (opc);
372} 386}
373 387
@@ -675,7 +689,6 @@ GNUNET_TESTBED_overlay_connect (void *op_cls,
675 data->p2 = p2; 689 data->p2 = p2;
676 data->cb = cb; 690 data->cb = cb;
677 data->cb_cls = cb_cls; 691 data->cb_cls = cb_cls;
678 data->state = OCD_INIT;
679 opc = GNUNET_malloc (sizeof (struct OperationContext)); 692 opc = GNUNET_malloc (sizeof (struct OperationContext));
680 opc->data = data; 693 opc->data = data;
681 opc->c = p1->controller; 694 opc->c = p1->controller;
diff --git a/src/testbed/testbed_api_peers.h b/src/testbed/testbed_api_peers.h
index 13eb1d036..f02079926 100644
--- a/src/testbed/testbed_api_peers.h
+++ b/src/testbed/testbed_api_peers.h
@@ -219,31 +219,14 @@ struct OverlayConnectData
219 struct OperationContext *sub_opc; 219 struct OperationContext *sub_opc;
220 220
221 /** 221 /**
222 * State information for this context data 222 * The starting time of this operation
223 */ 223 */
224 enum OCDState { 224 struct GNUNET_TIME_Absolute tstart;
225
226 /**
227 * The initial state
228 */
229 OCD_INIT,
230 225
231 /** 226 /**
232 * State where we attempt to acquire peer2's controller's configuration 227 * The timing slot index for this operation
233 */ 228 */
234 OCD_CFG_ACQUIRE, 229 unsigned int tslot_index;
235
236 /**
237 * State where we link peer1's controller to peer2's controller
238 */
239 OCD_LINK_CONTROLLERS,
240
241 /**
242 * State where we re-ask controller of peer1 to attempt an overlay connect
243 * between peer1 and peer2
244 */
245 OCD_REATTEMPT_OVERLAY_CONNECT
246 } state;
247 230
248}; 231};
249 232