Print the MPR selector set as part of the neighbour table by populating
[olsrd.git] / src / scheduler.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 Andreas T√łnnesen (andreto@ifi.uio.no)
4  *
5  * This file is part of the olsr.org OLSR daemon.
6  *
7  * olsr.org is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsr.org is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  * 
22  * $Id: scheduler.c,v 1.18 2004/11/15 15:50:08 tlopatic Exp $
23  *
24  */
25
26
27 #include "defs.h"
28 #include "scheduler.h"
29 #include "tc_set.h"
30 #include "link_set.h"
31 #include "duplicate_set.h"
32 #include "mpr_selector_set.h"
33 #include "mid_set.h"
34 #include "mpr.h"
35 #include "olsr.h"
36 #include "build_msg.h"
37
38
39 static float pollrate;
40
41
42
43 /**
44  *Main scheduler event loop. Polls at every
45  *sched_poll_interval and calls all functions
46  *that are timed out or that are triggered.
47  *Also calls the olsr_process_changes()
48  *function at every poll.
49  *
50  *
51  *@return nada
52  */
53
54 void
55 scheduler()
56 {
57   struct timespec remainder_spec;
58   struct timespec sleeptime_spec;
59
60   /*
61    *Used to calculate sleep time
62    */
63   struct timeval start_of_loop;
64   struct timeval end_of_loop;
65   struct timeval time_used;
66   struct timeval interval;
67   struct timeval sleeptime_val;
68
69   olsr_u32_t interval_usec;
70
71   struct event_entry *entry;
72   struct timeout_entry *time_out_entry;
73
74   struct interface *ifn;
75  
76   pollrate = olsr_cnf->pollrate;
77
78   interval_usec = (olsr_u32_t)(pollrate * 1000000);
79
80   interval.tv_sec = interval_usec / 1000000;
81   interval.tv_usec = interval_usec % 1000000;
82
83   olsr_printf(1, "Scheduler started - polling every %0.2f seconds\n", pollrate);
84
85   olsr_printf(3, "Max jitter is %f\n\n", max_jitter);
86
87
88
89   /* Main scheduler event loop */
90
91   for(;;)
92     {
93
94       gettimeofday(&start_of_loop, NULL);
95
96       /* Update the global timestamp */
97       gettimeofday(&now, NULL);
98       nowtm = gmtime((time_t *)&now.tv_sec);
99
100       while (nowtm == NULL)
101         {
102           nowtm = gmtime((time_t *)&now.tv_sec);
103         }
104
105
106       /* Run timout functions (before packet generation) */
107
108       time_out_entry = timeout_functions;
109       
110       while(time_out_entry)
111         {
112           time_out_entry->function();
113           time_out_entry = time_out_entry->next;
114         }
115
116       /* Update */
117       
118       olsr_process_changes();
119
120
121       /* Check for changes in topology */
122
123       if(changes)
124         {
125           // if the MPR selector set was update, we have to print
126           // the updated neighbour table, as it now contains an
127           // "MPRS" column
128
129           olsr_print_neighbor_table();
130
131           olsr_printf(3, "ANSN UPDATED %d\n\n", ansn);
132           ansn++;
133 #warning changes is set to OLSR_FALSE in scheduler now
134           changes = OLSR_FALSE;
135         }
136
137
138       /* Check scheduled events */
139
140       entry = event_functions;
141
142       /* UPDATED - resets timer upon triggered execution */
143       while(entry)
144         {
145           entry->since_last += pollrate;
146
147           /* Timed out */
148           if((entry->since_last > entry->interval) ||
149              /* Triggered */
150              ((entry->trigger != NULL) &&
151               (*(entry->trigger) == 1)))
152             {
153               /* Run scheduled function */
154               entry->function(entry->param);
155
156               /* Set jitter */
157               entry->since_last = (float) random()/RAND_MAX;
158               entry->since_last *= max_jitter;
159               
160               /* Reset trigger */
161               if(entry->trigger != NULL)
162                 *(entry->trigger) = 0;
163               
164               //olsr_printf(3, "Since_last jitter: %0.2f\n", entry->since_last);
165
166             }
167
168           entry = entry->next;
169         }
170
171
172
173       /* looping trough interfaces and emmittin pending data */
174       for (ifn = ifnet; ifn ; ifn = ifn->int_next) 
175         { 
176           if(net_output_pending(ifn) && TIMED_OUT(&fwdtimer[ifn->if_nr])) 
177             net_output(ifn);
178         }
179
180
181       gettimeofday(&end_of_loop, NULL);
182
183       timersub(&end_of_loop, &start_of_loop, &time_used);
184
185
186       //printf("Time to sleep: %ld\n", sleeptime.tv_nsec);
187       //printf("Time used: %ld\n", time_used.tv_usec/1000);
188
189       if(timercmp(&time_used, &interval, <))
190         {
191           timersub(&interval, &time_used, &sleeptime_val);
192           
193           // printf("sleeptime_val = %u.%06u\n",
194           //        sleeptime_val.tv_sec, sleeptime_val.tv_usec);
195           
196           sleeptime_spec.tv_sec = sleeptime_val.tv_sec;
197           sleeptime_spec.tv_nsec = sleeptime_val.tv_usec * 1000;
198           
199           while(nanosleep(&sleeptime_spec, &remainder_spec) < 0)
200             sleeptime_spec = remainder_spec;
201         }
202       
203     }//end for
204 }
205
206
207 /*
208  *
209  *@param initial how long utnil the first generation
210  *@param trigger pointer to a boolean indicating that
211  *this function should be triggered immediatley
212  */
213 int
214 olsr_register_scheduler_event(void (*event_function)(void *), 
215                               void *par,
216                               float interval, 
217                               float initial, 
218                               olsr_u8_t *trigger)
219 {
220   struct event_entry *new_entry;
221
222   olsr_printf(3, "Scheduler event registered int: %0.2f\n", interval);
223
224   /* check that this entry is not added already */
225   new_entry = event_functions;
226   while(new_entry)
227     {
228       if((new_entry->function == event_function) &&
229          (new_entry->param == par) &&
230          (new_entry->trigger == trigger) &&
231          (new_entry->interval == interval))
232         {
233           fprintf(stderr, "Register scheduler event: Event alread registered!\n");
234           olsr_syslog(OLSR_LOG_ERR, "Register scheduler event: Event alread registered!\n");
235           return 0;
236         }
237       new_entry = new_entry->next;
238     }
239
240   new_entry = olsr_malloc(sizeof(struct event_entry), "add scheduler event");
241
242   new_entry->function = event_function;
243   new_entry->param = par;
244   new_entry->interval = interval;
245   new_entry->since_last = interval - initial;
246   new_entry->next = event_functions;
247   new_entry->trigger = trigger;
248
249   event_functions = new_entry;
250
251   return 1;
252 }
253
254
255
256 /*
257  *
258  *@param initial how long utnil the first generation
259  *@param trigger pointer to a boolean indicating that
260  *this function should be triggered immediatley
261  */
262 int
263 olsr_remove_scheduler_event(void (*event_function)(void *), 
264                             void *par,
265                             float interval, 
266                             float initial, 
267                             olsr_u8_t *trigger)
268 {
269   struct event_entry *entry, *prev;
270
271   prev = NULL;
272   entry = event_functions;
273
274   while(entry)
275     {
276       if((entry->function == event_function) &&
277          (entry->param == par) &&
278          (entry->trigger == trigger) &&
279          (entry->interval == interval))
280         {
281           if(entry == event_functions)
282             {
283               event_functions = entry->next;
284             }
285           else
286             {
287               prev->next = entry->next;
288             }
289           return 1;
290         }
291
292       prev = entry;
293       entry = entry->next;
294     }
295
296   return 0;
297 }
298
299
300 int
301 olsr_register_timeout_function(void (*time_out_function)(void))
302 {
303   struct timeout_entry *new_entry;
304
305   /* check that this entry is not added already */
306   new_entry = timeout_functions;
307   while(new_entry)
308     {
309       if(new_entry->function == time_out_function)
310         {
311           fprintf(stderr, "Register scheduler timeout: Event alread registered!\n");
312           olsr_syslog(OLSR_LOG_ERR, "Register scheduler timeout: Event alread registered!\n");
313           return 0;
314         }
315       new_entry = new_entry->next;
316     }
317
318   new_entry = olsr_malloc(sizeof(struct timeout_entry), "scheduler add timeout");
319
320   new_entry->function = time_out_function;
321   new_entry->next = timeout_functions;
322
323   timeout_functions = new_entry;
324
325   return 1;
326 }
327
328
329
330 int
331 olsr_remove_timeout_function(void (*time_out_function)(void))
332 {
333   struct timeout_entry *entry, *prev;
334
335   /* check that this entry is not added already */
336   entry = timeout_functions;
337   prev = NULL;
338
339   while(entry)
340     {
341       if(entry->function == time_out_function)
342         {
343           if(entry == timeout_functions)
344             {
345               timeout_functions = entry->next;
346             }
347           else
348             {
349               prev->next = entry->next;
350             }
351           free(entry);
352           return 1;
353         }
354       prev = entry;
355       entry = entry->next;
356     }
357
358   return 0;
359 }
360