1 /*
2  * The olsr.org Optimized Link-State Routing daemon (olsrd)
3  *
4  * (c) by the OLSR project
5  *
6  * See our Git repository to find out who worked on this file
7  * and thus is a copyright holder on it.
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * * Redistributions of source code must retain the above copyright
16  *   notice, this list of conditions and the following disclaimer.
17  * * Redistributions in binary form must reproduce the above copyright
18  *   notice, this list of conditions and the following disclaimer in
19  *   the documentation and/or other materials provided with the
20  *   distribution.
21  * * Neither the name of olsr.org, olsrd nor the names of its
22  *   contributors may be used to endorse or promote products derived
23  *   from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  *
38  * Visit http://www.olsr.org for more information.
39  *
40  * If you find this software useful feel free to make a donation
41  * to the project. For more information see the website or contact
42  * the copyright holders.
43  *
44  */
45 
46 
47 #ifndef _OLSR_SCHEDULER
48 #define _OLSR_SCHEDULER
49 
50 #include "common/list.h"
51 
52 #include "olsr_types.h"
53 
54 #include <time.h>
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 #define TIMER_WHEEL_SLOTS 1024
63 #define TIMER_WHEEL_MASK (TIMER_WHEEL_SLOTS - 1)
64 
65 typedef void (*timer_cb_func) (void *); /* callback function */
66 
67 /*
68  * Our timer implementation is a based on individual timers arranged in
69  * a double linked list hanging of hash containers called a timer wheel slot.
70  * For every timer a timer_entry is created and attached to the timer wheel slot.
71  * When the timer fires, the timer_cb function is called with the
72  * context pointer.
73  * The implementation supports periodic and oneshot timers.
74  * For a periodic timer the timer_period field is set to non zero,
75  * which causes the timer to run forever until manually stopped.
76  */
77 struct timer_entry {
78   struct list_node timer_list;         /* Wheel membership */
79   uint32_t timer_clock;                /* when timer shall fire (absolute time) */
80   unsigned int timer_period;           /* set for periodical timers (relative time) */
81   struct olsr_cookie_info *timer_cookie;       /* used for diag stuff */
82   uint8_t timer_jitter_pct;            /* the jitter expressed in percent */
83   uint8_t timer_flags;                 /* misc flags */
84   unsigned int timer_random;           /* cache random() result for performance reasons */
85   timer_cb_func timer_cb;              /* callback function */
86   void *timer_cb_context;              /* context pointer */
87 };
88 
89 /* INLINE to recast from timer_list back to timer_entry */
90 LISTNODE2STRUCT(list2timer, struct timer_entry, timer_list);
91 
92 #define OLSR_TIMER_ONESHOT    0 /* One shot timer */
93 #define OLSR_TIMER_PERIODIC   1 /* Periodic timer */
94 
95 /* Timer flags */
96 #define OLSR_TIMER_RUNNING  ( 1u << 0)   /* this timer is running */
97 #define OLSR_TIMER_REMOVED  ( 1u << 1)   /* this timer is tagged for removal */
98 
99 /* Timers */
100 void olsr_init_timers(void);
101 void olsr_flush_timers(void);
102 void olsr_set_timer (struct timer_entry **, unsigned int, uint8_t, bool, timer_cb_func, void *, struct olsr_cookie_info *);
103 struct timer_entry *olsr_start_timer (unsigned int, uint8_t, bool, timer_cb_func, void *, struct olsr_cookie_info *);
104 void olsr_change_timer(struct timer_entry *, unsigned int, uint8_t, bool);
105 void olsr_stop_timer (struct timer_entry *);
106 
107 /* Printing timestamps */
108 const char *olsr_clock_string(uint32_t);
109 const char *olsr_wallclock_string(void);
110 
111 /* Main scheduler loop */
112 void olsr_scheduler(void);
113 void olsr_scheduler_stop(void);
114 
115 /*
116  * Provides a timestamp s1 milliseconds in the future
117  */
118 #define GET_TIMESTAMP(s1)	olsr_getTimestamp(s1)
119 
120 /* Compute the time in milliseconds when a timestamp will expire. */
121 #define TIME_DUE(s1)    olsr_getTimeDue(s1)
122 
123 /* Returns TRUE if a timestamp is expired */
124 #define TIMED_OUT(s1)	  olsr_isTimedOut(s1)
125 
126 /* Timer data */
127 extern uint32_t now_times;     /* current idea of times(2) reported uptime */
128 
129 
130 #define SP_PR_READ		0x01
131 #define SP_PR_WRITE		0x02
132 
133 #define SP_IMM_READ		0x04
134 #define SP_IMM_WRITE		0x08
135 
136 
137 typedef void (*socket_handler_func) (int fd, void *data, unsigned int flags);
138 
139 
140 struct olsr_socket_entry {
141   int fd;
142   socket_handler_func process_immediate;
143   socket_handler_func process_pollrate;
144   void *data;
145   unsigned int flags;
146   struct list_node socket_node;
147 };
148 
149 LISTNODE2STRUCT(list2socket, struct olsr_socket_entry, socket_node);
150 
151 /* deletion safe macro for socket list traversal */
152 #define OLSR_FOR_ALL_SOCKETS(socket) \
153 { \
154   struct list_node *_socket_node, *_next_socket_node; \
155   for (_socket_node = socket_head.next; \
156     _socket_node != &socket_head; \
157     _socket_node = _next_socket_node) { \
158     _next_socket_node = _socket_node->next; \
159     socket = list2socket(_socket_node);
160 #define OLSR_FOR_ALL_SOCKETS_END(socket) }}
161 
162 uint32_t olsr_times(void);
163 uint32_t olsr_getTimestamp (uint32_t s);
164 int32_t olsr_getTimeDue (uint32_t s);
165 bool olsr_isTimedOut (uint32_t s);
166 
167 void 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 enable_olsr_socket (int fd, socket_handler_func pf_pr, socket_handler_func pf_imm, unsigned int flags);
171 void 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 /* _OLSR_SCHEDULER */
183 
184 /*
185  * Local Variables:
186  * c-basic-offset: 2
187  * indent-tabs-mode: nil
188  * End:
189  */
190