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