ats-testing-preferences.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2010-2013 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file ats-tests/ats-testing-preferences.c
  18. * @brief ats benchmark: preference generator
  19. * @author Christian Grothoff
  20. * @author Matthias Wachs
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #include "ats-testing.h"
  25. static struct PreferenceGenerator *pg_head;
  26. static struct PreferenceGenerator *pg_tail;
  27. extern struct GNUNET_ATS_TEST_Topology *top;
  28. static double
  29. get_preference(struct PreferenceGenerator *pg)
  30. {
  31. struct GNUNET_TIME_Relative time_delta;
  32. double delta_value;
  33. double pref_value;
  34. /* Calculate the current preference value */
  35. switch (pg->type)
  36. {
  37. case GNUNET_ATS_TEST_TG_CONSTANT:
  38. pref_value = pg->base_value;
  39. break;
  40. case GNUNET_ATS_TEST_TG_LINEAR:
  41. time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
  42. /* Calculate point of time in the current period */
  43. time_delta.rel_value_us = time_delta.rel_value_us %
  44. pg->duration_period.rel_value_us;
  45. delta_value = ((double)time_delta.rel_value_us /
  46. pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
  47. if ((pg->max_value < pg->base_value) &&
  48. ((pg->max_value - pg->base_value) > pg->base_value))
  49. {
  50. /* This will cause an underflow */
  51. GNUNET_break(0);
  52. }
  53. pref_value = pg->base_value + delta_value;
  54. break;
  55. case GNUNET_ATS_TEST_TG_RANDOM:
  56. delta_value = (double)GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK,
  57. 10000 * (pg->max_value - pg->base_value)) / 10000;
  58. pref_value = pg->base_value + delta_value;
  59. break;
  60. case GNUNET_ATS_TEST_TG_SINUS:
  61. time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
  62. /* Calculate point of time in the current period */
  63. time_delta.rel_value_us = time_delta.rel_value_us %
  64. pg->duration_period.rel_value_us;
  65. if ((pg->max_value - pg->base_value) > pg->base_value)
  66. {
  67. /* This will cause an underflow for second half of sinus period,
  68. * will be detected in general when experiments are loaded */
  69. GNUNET_break(0);
  70. }
  71. delta_value = (pg->max_value - pg->base_value) *
  72. sin((2 * M_PI) / ((double)pg->duration_period.rel_value_us) *
  73. time_delta.rel_value_us);
  74. pref_value = pg->base_value + delta_value;
  75. break;
  76. default:
  77. pref_value = 0.0;
  78. break;
  79. }
  80. GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Current preference value is %f\n",
  81. pref_value);
  82. return pref_value;
  83. }
  84. static void
  85. set_pref_task(void *cls)
  86. {
  87. struct BenchmarkPartner *p = cls;
  88. double pref_value;
  89. p->pg->set_task = NULL;
  90. pref_value = get_preference(p->pg);
  91. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  92. "Setting preference for master [%u] and slave [%u] for %s to %f\n",
  93. p->me->no, p->dest->no,
  94. GNUNET_ATS_print_preference_type(p->pg->kind), pref_value);
  95. GNUNET_ATS_performance_change_preference(p->me->ats_perf_handle,
  96. &p->dest->id,
  97. p->pg->kind,
  98. pref_value,
  99. GNUNET_ATS_PREFERENCE_END);
  100. switch (p->pg->kind)
  101. {
  102. case GNUNET_ATS_PREFERENCE_BANDWIDTH:
  103. p->pref_bandwidth = pref_value;
  104. break;
  105. case GNUNET_ATS_PREFERENCE_LATENCY:
  106. p->pref_delay = pref_value;
  107. break;
  108. default:
  109. break;
  110. }
  111. p->pg->set_task = GNUNET_SCHEDULER_add_delayed(p->pg->frequency,
  112. set_pref_task, p);
  113. }
  114. /**
  115. * Generate between the source master and the partner and set preferences with a
  116. * value depending on the generator.
  117. *
  118. * @param src source
  119. * @param dest partner
  120. * @param type type of preferences to generate
  121. * @param base_value traffic base rate to send data with
  122. * @param value_rate traffic maximum rate to send data with
  123. * @param period duration of a period of preferences generation (~ 1/frequency)
  124. * @param frequency how long to generate preferences
  125. * @param kind ATS preference to generate
  126. * @return the preference generator
  127. */
  128. struct PreferenceGenerator *
  129. GNUNET_ATS_TEST_generate_preferences_start(struct BenchmarkPeer *src,
  130. struct BenchmarkPartner *dest,
  131. enum GeneratorType type,
  132. unsigned int base_value,
  133. unsigned int value_rate,
  134. struct GNUNET_TIME_Relative period,
  135. struct GNUNET_TIME_Relative frequency,
  136. enum GNUNET_ATS_PreferenceKind kind)
  137. {
  138. struct PreferenceGenerator *pg;
  139. if (NULL != dest->pg)
  140. {
  141. GNUNET_break(0);
  142. return NULL;
  143. }
  144. pg = GNUNET_new(struct PreferenceGenerator);
  145. GNUNET_CONTAINER_DLL_insert(pg_head, pg_tail, pg);
  146. pg->type = type;
  147. pg->src = src;
  148. pg->dest = dest;
  149. pg->kind = kind;
  150. pg->base_value = base_value;
  151. pg->max_value = value_rate;
  152. pg->duration_period = period;
  153. pg->frequency = frequency;
  154. pg->time_start = GNUNET_TIME_absolute_get();
  155. switch (type)
  156. {
  157. case GNUNET_ATS_TEST_TG_CONSTANT:
  158. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  159. "Setting up constant preference generator master[%u] `%s' and slave [%u] `%s' max %u Bips\n",
  160. dest->me->no, GNUNET_i2s(&dest->me->id),
  161. dest->dest->no, GNUNET_i2s(&dest->dest->id),
  162. base_value);
  163. break;
  164. case GNUNET_ATS_TEST_TG_LINEAR:
  165. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  166. "Setting up linear preference generator master[%u] `%s' and slave [%u] `%s' min %u Bips max %u Bips\n",
  167. dest->me->no, GNUNET_i2s(&dest->me->id),
  168. dest->dest->no, GNUNET_i2s(&dest->dest->id),
  169. base_value, value_rate);
  170. break;
  171. case GNUNET_ATS_TEST_TG_SINUS:
  172. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  173. "Setting up sinus preference generator master[%u] `%s' and slave [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
  174. dest->me->no, GNUNET_i2s(&dest->me->id),
  175. dest->dest->no, GNUNET_i2s(&dest->dest->id),
  176. base_value, value_rate);
  177. break;
  178. case GNUNET_ATS_TEST_TG_RANDOM:
  179. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  180. "Setting up random preference generator master[%u] `%s' and slave [%u] `%s' min %u Bips max %u Bps\n",
  181. dest->me->no, GNUNET_i2s(&dest->me->id),
  182. dest->dest->no, GNUNET_i2s(&dest->dest->id),
  183. base_value, value_rate);
  184. break;
  185. default:
  186. break;
  187. }
  188. dest->pg = pg;
  189. pg->set_task = GNUNET_SCHEDULER_add_now(&set_pref_task, dest);
  190. return pg;
  191. }
  192. void
  193. GNUNET_ATS_TEST_generate_preferences_stop(struct PreferenceGenerator *pg)
  194. {
  195. GNUNET_CONTAINER_DLL_remove(pg_head, pg_tail, pg);
  196. pg->dest->pg = NULL;
  197. if (NULL != pg->set_task)
  198. {
  199. GNUNET_SCHEDULER_cancel(pg->set_task);
  200. pg->set_task = NULL;
  201. }
  202. GNUNET_free(pg);
  203. }
  204. /**
  205. * Stop all preferences generators
  206. */
  207. void
  208. GNUNET_ATS_TEST_generate_preferences_stop_all()
  209. {
  210. struct PreferenceGenerator *cur;
  211. struct PreferenceGenerator *next;
  212. next = pg_head;
  213. for (cur = next; NULL != cur; cur = next)
  214. {
  215. next = cur->next;
  216. GNUNET_ATS_TEST_generate_preferences_stop(cur);
  217. }
  218. }
  219. /* end of file ats-testing-preferences.c */