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