6f649febe82eee12d5e0ea801471aca0b3bfab30
[olsrd.git] / src / scheduler.h
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
5  * Timer rewrite (c) 2008, Hannes Gredler (hannes@gredler.at)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  *   notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in
16  *   the documentation and/or other materials provided with the
17  *   distribution.
18  * * Neither the name of olsr.org, olsrd nor the names of its
19  *   contributors may be used to endorse or promote products derived
20  *   from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * Visit http://www.olsr.org for more information.
36  *
37  * If you find this software useful feel free to make a donation
38  * to the project. For more information see the website or contact
39  * the copyright holders.
40  *
41  */
42
43
44 #ifndef _OLSR_SCHEDULER
45 #define _OLSR_SCHEDULER
46
47 #include "common/list.h"
48
49 #include "olsr_types.h"
50
51 #include <time.h>
52
53 #define TIMER_WHEEL_SLOTS 256
54 #define TIMER_WHEEL_MASK (TIMER_WHEEL_SLOTS - 1)
55
56 /* Some defs for juggling with timers */
57 #define MSEC_PER_SEC 1000
58 #define USEC_PER_SEC 1000000
59 #define NSEC_PER_USEC 1000
60 #define USEC_PER_MSEC 1000
61
62 typedef void (*timer_cb_func)(void *);         /* callback function */
63
64 /*
65  * Our timer implementation is a based on individual timers arranged in
66  * a double linked list hanging of hash containers called a timer wheel slot.
67  * For every timer a timer_entry is created and attached to the timer wheel slot.
68  * When the timer fires, the timer_cb function is called with the
69  * context pointer.
70  * The implementation supports periodic and oneshot timers.
71  * For a periodic timer the timer_period field is set to non zero,
72  * which causes the timer to run forever until manually stopped.
73  */
74 struct timer_entry {
75   struct list_node timer_list;         /* Wheel membership */
76   clock_t timer_clock;                 /* when timer shall fire (absolute time) */
77   unsigned int timer_period;           /* set for periodical timers (relative time) */
78   olsr_cookie_t timer_cookie;          /* used for diag stuff */
79   uint8_t timer_jitter_pct;            /* the jitter expressed in percent */
80   uint8_t timer_flags;         /* misc flags */
81   unsigned int timer_random;           /* cache random() result for performance reasons */
82   timer_cb_func timer_cb;              /* callback function */
83   void *timer_cb_context;              /* context pointer */
84 };
85
86 /* inline to recast from timer_list back to timer_entry */
87 LISTNODE2STRUCT(list2timer, struct timer_entry, timer_list);
88
89 #define OLSR_TIMER_ONESHOT    0 /* One shot timer */
90 #define OLSR_TIMER_PERIODIC   1 /* Periodic timer */
91
92 /* Timer flags */
93 #define OLSR_TIMER_RUNNING  ( 1 << 0)   /* this timer is running */
94
95 /* Timers */
96 void olsr_init_timers(void);
97 void olsr_flush_timers(void);
98 void olsr_set_timer(struct timer_entry **, unsigned int, uint8_t, bool,
99                     timer_cb_func, void *, olsr_cookie_t);
100 struct timer_entry *EXPORT(olsr_start_timer)(unsigned int, uint8_t, bool,
101                                      timer_cb_func, void *, olsr_cookie_t);
102 void olsr_change_timer(struct timer_entry *, unsigned int, uint8_t, bool);
103 void olsr_stop_timer(struct timer_entry *);
104
105 /* Printing timestamps */
106 #ifndef NODEBUG
107 const char *olsr_clock_string(clock_t);
108 const char *olsr_wallclock_string(void);
109 #endif /* !NODEBUG */
110
111 /* Main scheduler loop */
112 void olsr_scheduler(void);
113
114 /*
115  * Provides a timestamp s1 milliseconds in the future according
116  * to system ticks returned by times(2)
117  * We cast the result of the division to clock_t. That serves two purposes:
118  * - it workarounds numeric underflows if the pollrate is <= 0.5
119  * - since we add "now_times" which is an integer, users (hopefully) expect
120  *   to get integeres as result (which is without the cast not guaranteed)
121  */
122 #define GET_TIMESTAMP(s1)       (now_times + (clock_t)((s1) / olsr_cnf->system_tick_divider))
123
124 /* Compute the time in milliseconds when a timestamp will expire. */
125 #define TIME_DUE(s1)    ((long)((s1) * olsr_cnf->system_tick_divider) - now_times)
126
127 /* Returns TRUE if a timestamp is expired */
128 #define TIMED_OUT(s1)   ((long)((s1) - now_times) < 0)
129
130 /* Timer data */
131 extern clock_t EXPORT(now_times); /* current idea of times(2) reported uptime */
132
133
134 #define SP_PR_READ              0x01
135 #define SP_PR_WRITE             0x02
136
137 #define SP_IMM_READ             0x04
138 #define SP_IMM_WRITE            0x08
139
140
141 typedef void (*socket_handler_func)(int fd, void *data, unsigned int flags);
142
143
144 struct olsr_socket_entry {
145   int fd;
146   socket_handler_func process_immediate;
147   socket_handler_func process_pollrate;
148   void *data;
149   unsigned int flags;
150   struct list_node socket_node;
151 };
152
153 LISTNODE2STRUCT(list2socket, struct olsr_socket_entry, socket_node);
154
155 /* deletion safe macro for socket list traversal */
156 #define OLSR_FOR_ALL_SOCKETS(socket) \
157 { \
158   struct list_node *_socket_node, *_next_socket_node; \
159   for (_socket_node = socket_head.next; \
160     _socket_node != &socket_head; \
161     _socket_node = _next_socket_node) { \
162     _next_socket_node = _socket_node->next; \
163     socket = list2socket(_socket_node);
164 #define OLSR_FOR_ALL_SOCKETS_END(socket) }}
165
166
167 void EXPORT(add_olsr_socket)(int fd, socket_handler_func pf_pr, socket_handler_func pf_imm, void *data, unsigned int flags);
168 int remove_olsr_socket(int fd, socket_handler_func pf_pr, socket_handler_func pf_imm);
169 void olsr_flush_sockets(void);
170 void EXPORT(enable_olsr_socket)(int fd, socket_handler_func pf_pr, socket_handler_func pf_imm, unsigned int flags);
171 void EXPORT(disable_olsr_socket)(int fd, socket_handler_func pf_pr, socket_handler_func pf_imm, unsigned int flags);
172
173 /*
174  * a wrapper around times(2). times(2) has the problem, that it may return -1
175  * in case of an err (e.g. EFAULT on the parameter) or immediately before an
176  * overrun (though it is not en error) just because the jiffies (or whatever
177  * the underlying kernel calls the smallest accountable time unit) are
178  * inherently "unsigned" (and always incremented).
179  */
180
181
182 #endif
183
184 /*
185  * Local Variables:
186  * c-basic-offset: 2
187  * indent-tabs-mode: nil
188  * End:
189  */