diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/testbed/standard_deviation.c | 129 | ||||
-rw-r--r-- | src/testbed/test_testbed_api.conf | 2 | ||||
-rw-r--r-- | src/testbed/testbed_api.c | 330 | ||||
-rw-r--r-- | src/testbed/testbed_api.h | 62 | ||||
-rw-r--r-- | src/testbed/testbed_api_peers.c | 19 | ||||
-rw-r--r-- | src/testbed/testbed_api_peers.h | 29 |
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 | |||
24 | struct 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 | ||
24 | struct SDHandle | 43 | struct 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 | ||
53 | struct SDHandle * | 87 | struct SDHandle * |
54 | GNUNET_TESTBED_SD_init () | 88 | SD_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 | ||
59 | void | 98 | void |
60 | GNUNET_TESTBED_SD_destroy (struct SDHandle *h) | 99 | SD_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 | ||
65 | void | 111 | void |
66 | GNUNET_TESTBED_SD_add_data (struct SDHandle *h, unsigned int amount) | 112 | SD_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 | */ |
87 | int | 152 | int |
88 | GNUNET_TESTBED_SD_deviation_factor (struct SDHandle *h, unsigned int amount) | 153 | SD_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) | |||
107 | int | 172 | int |
108 | main () | 173 | main () |
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] |
83 | AUTOSTART = NO | 83 | AUTOSTART = NO |
84 | 84 | ||
85 | [gns] | ||
86 | AUTOSTART = 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 | ||
251 | struct 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 | |||
270 | struct 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 | */ | ||
320 | static struct SDHandle * | ||
321 | SD_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 | */ | ||
338 | static void | ||
339 | SD_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 | |||
351 | static void | ||
352 | SD_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 | */ | ||
392 | static int | ||
393 | SD_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 | */ | ||
1472 | static void | ||
1473 | GNUNET_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 | */ | ||
2475 | unsigned int | ||
2476 | GNUNET_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 | |||
2492 | static void | ||
2493 | decide_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 | |||
2531 | int | ||
2532 | GNUNET_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 | */ | ||
2556 | void | ||
2557 | GNUNET_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 | */ | ||
184 | struct SDHandle; | ||
185 | |||
186 | |||
187 | /** | ||
188 | * A slot to record time taken by an overlay connect operation | ||
189 | */ | ||
190 | struct 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 | */ |
190 | struct GNUNET_TESTBED_Controller | 214 | struct 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 | ||
538 | unsigned int | ||
539 | GNUNET_TESTBED_get_tslot_ (struct GNUNET_TESTBED_Controller *c, void *key); | ||
540 | |||
541 | |||
542 | void | ||
543 | GNUNET_TESTBED_update_time_slot_ (struct GNUNET_TESTBED_Controller *c, | ||
544 | unsigned int index, | ||
545 | void *key, | ||
546 | struct GNUNET_TIME_Relative time); | ||
547 | |||
548 | |||
549 | int | ||
550 | GNUNET_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 | |||
362 | oprelease_overlay_connect (void *cls) | 364 | oprelease_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 | ||