diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2014-12-16 20:57:09 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2014-12-16 20:57:09 +0000 |
commit | cffaa8b4a6591c02325a368dcc7cd3b999d1ef60 (patch) | |
tree | cc6f7114ae1007a50b11825f3b689c8f5e0c569d /src/experimentation/gnunet-daemon-experimentation_scheduler.c | |
parent | acad9f12ac57373b60d8bb2c64fe1d0f1dc3a06d (diff) | |
download | gnunet-cffaa8b4a6591c02325a368dcc7cd3b999d1ef60.tar.gz gnunet-cffaa8b4a6591c02325a368dcc7cd3b999d1ef60.zip |
removing experimentation: replaced by sensors
Diffstat (limited to 'src/experimentation/gnunet-daemon-experimentation_scheduler.c')
-rw-r--r-- | src/experimentation/gnunet-daemon-experimentation_scheduler.c | 448 |
1 files changed, 0 insertions, 448 deletions
diff --git a/src/experimentation/gnunet-daemon-experimentation_scheduler.c b/src/experimentation/gnunet-daemon-experimentation_scheduler.c deleted file mode 100644 index c13434e9b..000000000 --- a/src/experimentation/gnunet-daemon-experimentation_scheduler.c +++ /dev/null | |||
@@ -1,448 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2009 Christian Grothoff (and other contributing authors) | ||
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., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file experimentation/gnunet-daemon-experimentation_scheduler.c | ||
23 | * @brief experimentation daemon: execute experiments | ||
24 | * @author Christian Grothoff | ||
25 | * @author Matthias Wachs | ||
26 | */ | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_core_service.h" | ||
30 | #include "gnunet_statistics_service.h" | ||
31 | #include "gnunet-daemon-experimentation.h" | ||
32 | |||
33 | /** | ||
34 | * An experiment is added during startup as not running NOT_RUNNING | ||
35 | * | ||
36 | * The scheduler then decides to schedule it and sends a request to the | ||
37 | * remote peer, if core cannot send since it is busy we wait for some time | ||
38 | * and change state to BUSY, if we can send we change to REQUESTED and wait | ||
39 | * for remote peers ACK. | ||
40 | * | ||
41 | * When we receive an ACK we change to STARTED and when scheduler decides that | ||
42 | * the experiment is finished we change to STOPPED. | ||
43 | */ | ||
44 | |||
45 | enum ExperimentState | ||
46 | { | ||
47 | /* Experiment is added and waiting to be executed */ | ||
48 | NOT_RUNNING, | ||
49 | /* Cannot send request to remote peer, core is busy*/ | ||
50 | BUSY, | ||
51 | /* We requested experiment and wait for remote peer to ACK */ | ||
52 | REQUESTED, | ||
53 | /* Experiment is running */ | ||
54 | STARTED, | ||
55 | /* Experiment is done */ | ||
56 | STOPPED | ||
57 | }; | ||
58 | |||
59 | struct ScheduledExperiment { | ||
60 | struct ScheduledExperiment *next; | ||
61 | struct ScheduledExperiment *prev; | ||
62 | |||
63 | struct Experiment *e; | ||
64 | struct Node *n; | ||
65 | int state; | ||
66 | int outbound; | ||
67 | GNUNET_SCHEDULER_TaskIdentifier task; | ||
68 | }; | ||
69 | |||
70 | struct ScheduledExperiment *waiting_in_head; | ||
71 | struct ScheduledExperiment *waiting_in_tail; | ||
72 | |||
73 | struct ScheduledExperiment *running_in_head; | ||
74 | struct ScheduledExperiment *running_in_tail; | ||
75 | |||
76 | struct ScheduledExperiment *waiting_out_head; | ||
77 | struct ScheduledExperiment *waiting_out_tail; | ||
78 | |||
79 | struct ScheduledExperiment *running_out_head; | ||
80 | struct ScheduledExperiment *running_out_tail; | ||
81 | |||
82 | |||
83 | static unsigned int experiments_scheduled; | ||
84 | static unsigned int experiments_outbound_running; | ||
85 | static unsigned int experiments_inbound_running; | ||
86 | static unsigned int experiments_requested; | ||
87 | |||
88 | |||
89 | static struct ScheduledExperiment * | ||
90 | find_experiment (struct ScheduledExperiment *head, struct ScheduledExperiment *tail, | ||
91 | struct Node *n, struct Experiment *e, int outbound) | ||
92 | { | ||
93 | struct ScheduledExperiment *cur; | ||
94 | for (cur = head; NULL != cur; cur = cur->next) | ||
95 | { | ||
96 | if ((cur->n == n) && (cur->e == e) && (cur->outbound == outbound)) /* Node and experiment are equal */ | ||
97 | break; | ||
98 | } | ||
99 | return cur; | ||
100 | } | ||
101 | |||
102 | static void | ||
103 | request_timeout (void *cls,const struct GNUNET_SCHEDULER_TaskContext* tc) | ||
104 | { | ||
105 | struct ScheduledExperiment *se = cls; | ||
106 | se->task = GNUNET_SCHEDULER_NO_TASK; | ||
107 | |||
108 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Peer `%s' did not respond to request for experiment `%s'\n"), | ||
109 | GNUNET_i2s (&se->n->id), se->e->name); | ||
110 | |||
111 | GNUNET_CONTAINER_DLL_remove (waiting_out_head, waiting_out_tail, se); | ||
112 | GNUNET_free (se); | ||
113 | |||
114 | /* Remove experiment */ | ||
115 | GNUNET_assert (experiments_requested > 0); | ||
116 | experiments_requested --; | ||
117 | GNUNET_STATISTICS_set (GED_stats, "# experiments requested", experiments_requested, GNUNET_NO); | ||
118 | } | ||
119 | |||
120 | static void run_experiment_inbound (void *cls,const struct GNUNET_SCHEDULER_TaskContext* tc) | ||
121 | { | ||
122 | struct ScheduledExperiment *se = cls; | ||
123 | struct GNUNET_TIME_Relative start; | ||
124 | struct GNUNET_TIME_Relative end; | ||
125 | |||
126 | se->task = GNUNET_SCHEDULER_NO_TASK; | ||
127 | |||
128 | switch (se->state) { | ||
129 | case NOT_RUNNING: | ||
130 | /* Send START_ACK message */ | ||
131 | GED_nodes_send_start_ack (se->n, se->e); | ||
132 | se->state = REQUESTED; | ||
133 | /* Schedule to run */ | ||
134 | start = GNUNET_TIME_absolute_get_remaining(se->e->start); | ||
135 | if (0 == start.rel_value_us) | ||
136 | se->task = GNUNET_SCHEDULER_add_now (&run_experiment_inbound, se); | ||
137 | else | ||
138 | se->task = GNUNET_SCHEDULER_add_delayed (start, &run_experiment_inbound, se); | ||
139 | break; | ||
140 | case REQUESTED: | ||
141 | experiments_inbound_running ++; | ||
142 | GNUNET_STATISTICS_set (GED_stats, "# experiments inbound running", experiments_inbound_running, GNUNET_NO); | ||
143 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting inbound experiment `%s' with peer `%s'\n"), | ||
144 | se->e->name, GNUNET_i2s (&se->n->id)); | ||
145 | se->state = STARTED; | ||
146 | se->task = GNUNET_SCHEDULER_add_now (&run_experiment_inbound, se); | ||
147 | break; | ||
148 | case STARTED: | ||
149 | /* Experiment is running */ | ||
150 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running %s experiment `%s' peer for `%s'\n", | ||
151 | "inbound", GNUNET_i2s (&se->n->id), se->e->name); | ||
152 | |||
153 | /* do work here */ | ||
154 | |||
155 | /* Reschedule */ | ||
156 | end = GNUNET_TIME_absolute_get_remaining(GNUNET_TIME_absolute_add (se->e->stop, se->e->frequency)); | ||
157 | if (0 == end.rel_value_us) | ||
158 | { | ||
159 | se->state = STOPPED; | ||
160 | return; /* End of experiment is reached */ | ||
161 | } | ||
162 | /* Reschedule */ | ||
163 | se->task = GNUNET_SCHEDULER_add_delayed (se->e->frequency, &run_experiment_inbound, se); | ||
164 | break; | ||
165 | case STOPPED: | ||
166 | /* Experiment expired */ | ||
167 | break; | ||
168 | default: | ||
169 | break; | ||
170 | } | ||
171 | |||
172 | } | ||
173 | |||
174 | static void run_experiment_outbound (void *cls,const struct GNUNET_SCHEDULER_TaskContext* tc) | ||
175 | { | ||
176 | struct ScheduledExperiment *se = cls; | ||
177 | struct GNUNET_TIME_Relative end; | ||
178 | |||
179 | se->task = GNUNET_SCHEDULER_NO_TASK; | ||
180 | |||
181 | switch (se->state) { | ||
182 | case NOT_RUNNING: | ||
183 | /* Send START message */ | ||
184 | GED_nodes_send_start (se->n, se->e); | ||
185 | se->state = REQUESTED; | ||
186 | se->task = GNUNET_SCHEDULER_add_delayed (EXP_RESPONSE_TIMEOUT, &request_timeout, se); | ||
187 | experiments_requested ++; | ||
188 | GNUNET_STATISTICS_set (GED_stats, "# experiments requested", experiments_requested, GNUNET_NO); | ||
189 | break; | ||
190 | case REQUESTED: | ||
191 | /* Expecting START_ACK */ | ||
192 | GNUNET_break (0); | ||
193 | break; | ||
194 | case STARTED: | ||
195 | /* Experiment is running */ | ||
196 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running %s experiment `%s' peer for `%s'\n", | ||
197 | "outbound", GNUNET_i2s (&se->n->id), se->e->name); | ||
198 | |||
199 | /* do work here */ | ||
200 | |||
201 | /* Reschedule */ | ||
202 | end = GNUNET_TIME_absolute_get_remaining(GNUNET_TIME_absolute_add (se->e->stop, se->e->frequency)); | ||
203 | if (0 == end.rel_value_us) | ||
204 | { | ||
205 | se->state = STOPPED; | ||
206 | return; /* End of experiment is reached */ | ||
207 | } | ||
208 | /* Reschedule */ | ||
209 | se->task = GNUNET_SCHEDULER_add_delayed (se->e->frequency, &run_experiment_outbound, se); | ||
210 | break; | ||
211 | case STOPPED: | ||
212 | /* Experiment expired */ | ||
213 | break; | ||
214 | default: | ||
215 | break; | ||
216 | } | ||
217 | } | ||
218 | |||
219 | |||
220 | /** | ||
221 | * Handle a START message from a remote node | ||
222 | * | ||
223 | * @param n the node | ||
224 | * @param e the experiment | ||
225 | */ | ||
226 | void | ||
227 | GED_scheduler_handle_start (struct Node *n, struct Experiment *e) | ||
228 | { | ||
229 | if ((NULL != find_experiment (waiting_in_head, waiting_in_tail, n, e, GNUNET_NO)) || | ||
230 | (NULL != find_experiment (running_in_head, running_in_tail, n, e, GNUNET_NO))) | ||
231 | { | ||
232 | GNUNET_break_op (0); | ||
233 | return; | ||
234 | } | ||
235 | |||
236 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
237 | "Received %s message from peer %s for experiment `%s'\n", | ||
238 | "START", GNUNET_i2s (&n->id), e->name); | ||
239 | GED_scheduler_add (n, e, GNUNET_NO); | ||
240 | } | ||
241 | |||
242 | |||
243 | /** | ||
244 | * Handle a START_ACK message from a remote node | ||
245 | * | ||
246 | * @param n the node | ||
247 | * @param e the experiment | ||
248 | */ | ||
249 | void | ||
250 | GED_scheduler_handle_start_ack (struct Node *n, struct Experiment *e) | ||
251 | { | ||
252 | struct ScheduledExperiment *se; | ||
253 | |||
254 | if (NULL == (se = find_experiment (waiting_out_head, waiting_out_tail, n, e, GNUNET_YES))) | ||
255 | { | ||
256 | GNUNET_break (0); | ||
257 | return; | ||
258 | } | ||
259 | |||
260 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %s message from peer %s for requested experiment `%s'\n", | ||
261 | "START_ACK", GNUNET_i2s (&n->id), e->name); | ||
262 | |||
263 | if (GNUNET_SCHEDULER_NO_TASK != se->task) | ||
264 | { | ||
265 | GNUNET_SCHEDULER_cancel (se->task); /* *Canceling timeout task */ | ||
266 | se->task = GNUNET_SCHEDULER_NO_TASK; | ||
267 | } | ||
268 | |||
269 | /* Remove from waiting list, add to running list */ | ||
270 | GNUNET_CONTAINER_DLL_remove (waiting_out_head, waiting_out_tail, se); | ||
271 | GNUNET_CONTAINER_DLL_insert (running_out_head, running_out_tail, se); | ||
272 | |||
273 | /* Change state and schedule to run */ | ||
274 | experiments_outbound_running ++; | ||
275 | GNUNET_STATISTICS_set (GED_stats, "# experiments outbound running", experiments_outbound_running, GNUNET_NO); | ||
276 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting outbound experiment `%s' with peer `%s'\n"), | ||
277 | e->name, GNUNET_i2s (&n->id)); | ||
278 | se->state = STARTED; | ||
279 | se->task = GNUNET_SCHEDULER_add_now (&run_experiment_outbound, se); | ||
280 | } | ||
281 | |||
282 | |||
283 | /** | ||
284 | * Handle a STOP message from a remote node | ||
285 | * | ||
286 | * @param n the node | ||
287 | * @param e the experiment | ||
288 | */ | ||
289 | void | ||
290 | GED_scheduler_handle_stop (struct Node *n, struct Experiment *e) | ||
291 | { | ||
292 | struct ScheduledExperiment *se; | ||
293 | |||
294 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Received %s message from peer %s for experiment `%s'\n"), | ||
295 | "STOP", GNUNET_i2s (&n->id), e->name); | ||
296 | |||
297 | if (NULL != (se = find_experiment (waiting_in_head, waiting_in_tail, n, e, GNUNET_NO))) | ||
298 | { | ||
299 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %s message from peer %s for waiting experiment `%s'\n", | ||
300 | "STOP", GNUNET_i2s (&n->id), e->name); | ||
301 | } | ||
302 | |||
303 | if (NULL != (se = find_experiment (running_in_head, running_in_tail, n, e, GNUNET_NO))) | ||
304 | { | ||
305 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %s message from peer %s for running experiment `%s'\n", | ||
306 | "STOP", GNUNET_i2s (&n->id), e->name); | ||
307 | } | ||
308 | |||
309 | } | ||
310 | |||
311 | /** | ||
312 | * Add a new experiment for a node | ||
313 | * | ||
314 | * @param n the node | ||
315 | * @param e the experiment | ||
316 | * @param outbound are we initiator (GNUNET_YES) or client (GNUNET_NO)? | ||
317 | */ | ||
318 | void | ||
319 | GED_scheduler_add (struct Node *n, struct Experiment *e, int outbound) | ||
320 | { | ||
321 | struct ScheduledExperiment *se; | ||
322 | struct GNUNET_TIME_Relative start; | ||
323 | struct GNUNET_TIME_Relative end; | ||
324 | |||
325 | GNUNET_assert ((GNUNET_YES == outbound) || (GNUNET_NO == outbound)); | ||
326 | |||
327 | start = GNUNET_TIME_absolute_get_remaining(e->start); | ||
328 | end = GNUNET_TIME_absolute_get_remaining(e->stop); | ||
329 | if (0 == end.rel_value_us) | ||
330 | return; /* End of experiment is reached */ | ||
331 | |||
332 | /* Add additional checks here if required */ | ||
333 | se = GNUNET_new (struct ScheduledExperiment); | ||
334 | se->state = NOT_RUNNING; | ||
335 | se->outbound = outbound; | ||
336 | se->e = e; | ||
337 | se->n = n; | ||
338 | |||
339 | if (GNUNET_YES == outbound) | ||
340 | { | ||
341 | if (0 == start.rel_value_us) | ||
342 | se->task = GNUNET_SCHEDULER_add_now (&run_experiment_outbound, se); | ||
343 | else | ||
344 | se->task = GNUNET_SCHEDULER_add_delayed (start, &run_experiment_outbound, se); | ||
345 | GNUNET_CONTAINER_DLL_insert (waiting_out_head, waiting_out_tail, se); | ||
346 | } | ||
347 | else | ||
348 | { | ||
349 | if (0 == start.rel_value_us) | ||
350 | se->task = GNUNET_SCHEDULER_add_now (&run_experiment_inbound, se); | ||
351 | else | ||
352 | se->task = GNUNET_SCHEDULER_add_delayed (start, &run_experiment_inbound, se); | ||
353 | GNUNET_CONTAINER_DLL_insert (waiting_in_head, waiting_in_tail, se); | ||
354 | } | ||
355 | |||
356 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added %s experiment `%s' for node to be scheduled\n", | ||
357 | (GNUNET_YES == outbound) ? "outbound" : "inbound", e->name, GNUNET_i2s(&se->n->id)); | ||
358 | experiments_scheduled ++; | ||
359 | GNUNET_STATISTICS_set (GED_stats, "# experiments scheduled", experiments_scheduled, GNUNET_NO); | ||
360 | |||
361 | } | ||
362 | |||
363 | /** | ||
364 | * Start the scheduler component | ||
365 | */ | ||
366 | void | ||
367 | GED_scheduler_start () | ||
368 | { | ||
369 | experiments_requested = 0; | ||
370 | experiments_scheduled = 0; | ||
371 | } | ||
372 | |||
373 | |||
374 | /** | ||
375 | * Stop the scheduler component | ||
376 | */ | ||
377 | void | ||
378 | GED_scheduler_stop () | ||
379 | { | ||
380 | struct ScheduledExperiment *cur; | ||
381 | struct ScheduledExperiment *next; | ||
382 | |||
383 | next = waiting_in_head; | ||
384 | while (NULL != (cur = next)) | ||
385 | { | ||
386 | next = cur->next; | ||
387 | GNUNET_CONTAINER_DLL_remove (waiting_in_head, waiting_in_tail, cur); | ||
388 | if (GNUNET_SCHEDULER_NO_TASK != cur->task) | ||
389 | { | ||
390 | GNUNET_SCHEDULER_cancel (cur->task); | ||
391 | cur->task = GNUNET_SCHEDULER_NO_TASK; | ||
392 | } | ||
393 | GNUNET_free (cur); | ||
394 | GNUNET_assert (experiments_scheduled > 0); | ||
395 | experiments_scheduled --; | ||
396 | GNUNET_STATISTICS_set (GED_stats, "# experiments scheduled", experiments_scheduled, GNUNET_NO); | ||
397 | } | ||
398 | |||
399 | next = running_in_head; | ||
400 | while (NULL != (cur = next)) | ||
401 | { | ||
402 | next = cur->next; | ||
403 | GNUNET_CONTAINER_DLL_remove (running_in_head, running_in_tail, cur); | ||
404 | if (GNUNET_SCHEDULER_NO_TASK != cur->task) | ||
405 | { | ||
406 | GNUNET_SCHEDULER_cancel (cur->task); | ||
407 | cur->task = GNUNET_SCHEDULER_NO_TASK; | ||
408 | } | ||
409 | GNUNET_free (cur); | ||
410 | GNUNET_assert (experiments_outbound_running > 0); | ||
411 | experiments_inbound_running --; | ||
412 | GNUNET_STATISTICS_set (GED_stats, "# experiments inbound running", experiments_inbound_running, GNUNET_NO); | ||
413 | } | ||
414 | |||
415 | next = waiting_out_head; | ||
416 | while (NULL != (cur = next)) | ||
417 | { | ||
418 | next = cur->next; | ||
419 | GNUNET_CONTAINER_DLL_remove (waiting_out_head, waiting_out_tail, cur); | ||
420 | if (GNUNET_SCHEDULER_NO_TASK != cur->task) | ||
421 | { | ||
422 | GNUNET_SCHEDULER_cancel (cur->task); | ||
423 | cur->task = GNUNET_SCHEDULER_NO_TASK; | ||
424 | } | ||
425 | GNUNET_free (cur); | ||
426 | GNUNET_assert (experiments_scheduled > 0); | ||
427 | experiments_scheduled --; | ||
428 | GNUNET_STATISTICS_set (GED_stats, "# experiments scheduled", experiments_scheduled, GNUNET_NO); | ||
429 | } | ||
430 | |||
431 | next = running_out_head; | ||
432 | while (NULL != (cur = next)) | ||
433 | { | ||
434 | next = cur->next; | ||
435 | GNUNET_CONTAINER_DLL_remove (running_out_head, running_out_tail, cur); | ||
436 | if (GNUNET_SCHEDULER_NO_TASK != cur->task) | ||
437 | { | ||
438 | GNUNET_SCHEDULER_cancel (cur->task); | ||
439 | cur->task = GNUNET_SCHEDULER_NO_TASK; | ||
440 | } | ||
441 | GNUNET_free (cur); | ||
442 | GNUNET_assert (experiments_outbound_running > 0); | ||
443 | experiments_outbound_running --; | ||
444 | GNUNET_STATISTICS_set (GED_stats, "# experiments outbound running", experiments_outbound_running, GNUNET_NO); | ||
445 | } | ||
446 | } | ||
447 | |||
448 | /* end of gnunet-daemon-experimentation_scheduler.c */ | ||