Split scheduler into olsr_timer and olsr_socket
authorHenning Rogge <hrogge@googlemail.com>
Mon, 14 Feb 2011 20:08:05 +0000 (21:08 +0100)
committerHenning Rogge <hrogge@googlemail.com>
Mon, 14 Feb 2011 20:08:05 +0000 (21:08 +0100)
33 files changed:
lib/arprefresh/src/olsrd_arprefresh.c
lib/arproaming/src/olsrd_arproaming.c
lib/bmf/src/PacketHistory.c
lib/bmf/src/olsrd_plugin.c
lib/cl_roam/src/cl_roam.c
lib/dyn_gw/src/olsrd_dyn_gw.c
lib/dyn_gw_plain/src/olsrd_dyn_gw_plain.c
lib/lq_etx_ff/src/lq_plugin_etx_ff.c
lib/mdns/src/olsrd_plugin.c
lib/nameservice/src/mapwrite.c
lib/nameservice/src/nameservice.c
lib/obamp/src/olsrd_plugin.c
lib/quagga/src/olsrd_plugin.c
lib/secure/src/olsrd_secure.c
lib/watchdog/src/olsrd_plugin.c
src/duplicate_set.c
src/hna_set.c
src/interfaces.c
src/link_set.c
src/lq_mpr.c
src/main.c
src/mid_set.c
src/neighbor_table.c
src/olsr.c
src/olsr_comport.c
src/olsr_comport_txt.c
src/olsr_socket.c [new file with mode: 0644]
src/olsr_socket.h [moved from src/scheduler.h with 53% similarity]
src/olsr_timer.c [moved from src/scheduler.c with 67% similarity]
src/olsr_timer.h [new file with mode: 0644]
src/tc_set.h
src/unix/ifnet.c
src/win32/ifnet.c

index 8673594..5514b38 100644 (file)
@@ -62,7 +62,8 @@
 #include <unistd.h>
 
 #include "olsrd_arprefresh.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "os_net.h"
 #include "olsr_logging.h"
 #include "olsr_cfg.h"
index b5c47e1..00dddb1 100644 (file)
@@ -52,7 +52,8 @@
 #include "defs.h"
 #include "olsr_types.h"
 #include "olsr_logging.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "plugin_util.h"
 #include "olsr_ip_prefix_list.h"
 #include "net_olsr.h"
index 4787fc6..e49fe24 100644 (file)
@@ -52,7 +52,8 @@
 /* OLSRD includes */
 #include "defs.h"               /* GET_TIMESTAMP, TIMED_OUT */
 #include "olsr.h"
-#include "scheduler.h"          /* now_times */
+#include "olsr_timer.h"
+#include "olsr_socket.h"          /* now_times */
 
 /* Plugin includes */
 #include "Packet.h"
index 9f397d0..2506b5a 100644 (file)
@@ -46,7 +46,8 @@
 #include "plugin.h"
 #include "plugin_util.h"
 #include "defs.h"               /* uint8_t, olsr_cnf */
-#include "scheduler.h"          /* olsr_timer_start() */
+#include "olsr_timer.h"
+#include "olsr_socket.h"          /* olsr_timer_start() */
 #include "olsr_cfg.h"           /* olsr_cnf() */
 #include "olsr_memcookie.h"        /* olsr_memcookie_add() */
 #include "olsr_logging.h"
index 239b2a1..59cc6c1 100644 (file)
@@ -41,7 +41,8 @@
 #include "cl_roam.h"
 #include "olsr_types.h"
 #include "ipcalc.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr.h"
 #include "olsr_memcookie.h"
 #include "olsr_ip_prefix_list.h"
index 63d2dca..1a3ed43 100644 (file)
@@ -48,7 +48,8 @@
 #include "olsr.h"
 #include "defs.h"
 #include "ipcalc.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr_memcookie.h"
 #include "olsr_ip_prefix_list.h"
 #include "olsr_logging.h"
index 0f75a00..8a688a9 100644 (file)
@@ -42,7 +42,8 @@
 #include "olsrd_dyn_gw_plain.h"
 #include "olsr_types.h"
 #include "ipcalc.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr.h"
 #include "olsr_memcookie.h"
 #include "olsr_ip_prefix_list.h"
index 8831d91..9880302 100644 (file)
@@ -48,7 +48,8 @@
 #include "lq_plugin_etx_ff.h"
 #include "parser.h"
 #include "mid_set.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr_logging.h"
 #include "common/string.h"
 #include "neighbor_table.h"
index 0393a21..02ac122 100644 (file)
@@ -46,7 +46,8 @@
 #include "plugin.h"
 #include "plugin_util.h"
 #include "defs.h"               /* uint8_t, olsr_cnf */
-#include "scheduler.h"          /* olsr_timer_start() */
+#include "olsr_timer.h"
+#include "olsr_socket.h"          /* olsr_timer_start() */
 #include "olsr_cfg.h"           /* olsr_cnf() */
 #include "olsr_memcookie.h"        /* olsr_memcookie_add() */
 
index 0c0f1d0..06459a3 100644 (file)
@@ -49,7 +49,8 @@
 #include <sys/stat.h>
 
 #include "defs.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "nameservice.h"
 #include "mid_set.h"
 #include "tc_set.h"
index 4272e6b..edb3486 100644 (file)
@@ -61,7 +61,8 @@
 #include "net_olsr.h"
 #include "routing_table.h"
 #include "olsr_time.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "parser.h"
 #include "duplicate_set.h"
 #include "tc_set.h"
index 57f1b48..03f1b50 100644 (file)
@@ -50,7 +50,8 @@
 #include "plugin_loader.h"
 #include "plugin_util.h"
 #include "defs.h"               /* uint8_t, olsr_cnf */
-#include "scheduler.h"          /* olsr_timer_start() */
+#include "olsr_timer.h"
+#include "olsr_socket.h"          /* olsr_timer_start() */
 #include "olsr_cfg.h"           /* olsr_cnf() */
 #include "olsr_memcookie.h"        /* olsr_memcookie_add() */
 
index e2a9fd1..5bedb6f 100644 (file)
@@ -24,7 +24,8 @@
 
 #include "plugin.h"
 #include "plugin_util.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "defs.h"
 #include "quagga.h"
 #include "net_olsr.h"
index 571de60..968ce3a 100644 (file)
@@ -60,7 +60,8 @@
 #include "ipcalc.h"
 #include "olsr.h"
 #include "parser.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "net_olsr.h"
 #include "common/string.h"
 #include "olsr_logging.h"
index 3d2b484..4a0311a 100644 (file)
@@ -49,7 +49,8 @@
 #include "olsrd_plugin.h"
 #include "olsr.h"
 #include "defs.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr_memcookie.h"
 #include "olsr_logging.h"
 
index da70725..b790872 100644 (file)
@@ -44,7 +44,8 @@
 #include "common/avl.h"
 #include "olsr.h"
 #include "mid_set.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr_time.h"
 #include "olsr_memcookie.h"
 #include "olsr_logging.h"
index 00bff88..66ad1e8 100644 (file)
@@ -44,7 +44,8 @@
 #include "defs.h"
 #include "parser.h"
 #include "olsr.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "net_olsr.h"
 #include "tc_set.h"
 #include "olsr_ip_prefix_list.h"
index 0c5b30b..20222c4 100644 (file)
@@ -41,7 +41,8 @@
 
 #include "defs.h"
 #include "interfaces.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr.h"
 #include "parser.h"
 #include "net_olsr.h"
index 1abefa4..7ec6442 100644 (file)
@@ -48,7 +48,8 @@
 #include "mid_set.h"
 #include "neighbor_table.h"
 #include "olsr.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr_spf.h"
 #include "net_olsr.h"
 #include "ipcalc.h"
index a4e3e39..0f5fb5b 100644 (file)
@@ -43,7 +43,8 @@
 #include "neighbor_table.h"
 #include "link_set.h"
 #include "lq_mpr.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "lq_plugin.h"
 
 void
index 0266ec9..7f0b1ee 100644 (file)
@@ -50,7 +50,8 @@
 #include "common/avl_olsr_comp.h"
 #include "olsr.h"
 #include "ipcalc.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "parser.h"
 #include "plugin_loader.h"
 #include "os_apm.h"
@@ -242,7 +243,8 @@ main(int argc, char *argv[])
   olsr_memcookie_init();
 
   /* Initialize timers and scheduler part */
-  olsr_init_timers();
+  olsr_timer_init();
+  olsr_socket_init();
 
   /* initialize callback system */
   olsr_callback_init();
@@ -420,7 +422,7 @@ main(int argc, char *argv[])
 
   /* Starting scheduler */
   app_state = STATE_RUNNING;
-  olsr_scheduler();
+  olsr_timer_scheduler();
 
   olsr_timer_stop(tc_gen_timer);
   tc_gen_timer = NULL;
@@ -581,7 +583,7 @@ olsr_shutdown(void)
   olsr_socket_cleanup();
 
   /* Stop and delete all timers. */
-  olsr_flush_timers();
+  olsr_timer_cleanup();
 
   /* Remove parser hooks */
   olsr_deinit_parser();
index 37ac4a2..b9c8ea8 100644 (file)
@@ -43,7 +43,8 @@
 #include "defs.h"
 #include "mid_set.h"
 #include "olsr.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "neighbor_table.h"
 #include "link_set.h"
 #include "tc_set.h"
index 94d6077..8a90b10 100644 (file)
@@ -44,7 +44,8 @@
 #include "mid_set.h"
 #include "neighbor_table.h"
 #include "olsr.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "link_set.h"
 #include "net_olsr.h"
 #include "olsr_logging.h"
index 4ee6d25..820e3ff 100644 (file)
@@ -51,7 +51,8 @@
 #include "mid_set.h"
 #include "lq_mpr.h"
 #include "olsr_spf.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "neighbor_table.h"
 #include "lq_packet.h"
 #include "common/avl.h"
index 4f1f245..e03e717 100644 (file)
@@ -52,7 +52,8 @@
 #include "defs.h"
 #include "olsr_logging.h"
 #include "olsr_cfg.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr_memcookie.h"
 #include "common/autobuf.h"
 #include "common/avl.h"
index b5c2076..d87ad9b 100644 (file)
@@ -48,7 +48,8 @@
 #include "olsr_ip_acl.h"
 #include "olsr.h"
 #include "ipcalc.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr_comport.h"
 #include "olsr_comport_txt.h"
 #include "plugin_loader.h"
diff --git a/src/olsr_socket.c b/src/olsr_socket.c
new file mode 100644 (file)
index 0000000..0a8070e
--- /dev/null
@@ -0,0 +1,273 @@
+
+/*
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)
+ * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of olsr.org, olsrd nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Visit http://www.olsr.org for more information.
+ *
+ * If you find this software useful feel free to make a donation
+ * to the project. For more information see the website or contact
+ * the copyright holders.
+ *
+ */
+
+#include <unistd.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "common/avl.h"
+#include "common/avl_olsr_comp.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
+#include "link_set.h"
+#include "olsr.h"
+#include "olsr_memcookie.h"
+#include "os_net.h"
+#include "os_time.h"
+#include "olsr_logging.h"
+
+/* Head of all OLSR used sockets */
+struct list_entity socket_head;
+
+void
+olsr_socket_init(void) {
+  list_init_head(&socket_head);
+}
+
+/**
+ * Close and free all sockets.
+ */
+void
+olsr_socket_cleanup(void)
+{
+  struct olsr_socket_entry *entry, *iterator;
+
+  OLSR_FOR_ALL_SOCKETS(entry, iterator) {
+    os_close(entry->fd);
+    list_remove(&entry->socket_node);
+    free(entry);
+  }
+}
+
+/**
+ * Add a socket and handler to the socketset
+ * beeing used in the main select(2) loop
+ * in listen_loop
+ *
+ *@param fd the socket
+ *@param pf the processing function
+ */
+void
+olsr_socket_add(int fd, socket_handler_func pf_imm, void *data, unsigned int flags)
+{
+  struct olsr_socket_entry *new_entry;
+
+  if (fd < 0 || pf_imm == NULL) {
+    OLSR_WARN(LOG_SCHEDULER, "Bogus socket entry - not registering...");
+    return;
+  }
+  OLSR_DEBUG(LOG_SCHEDULER, "Adding OLSR socket entry %d\n", fd);
+
+  new_entry = olsr_malloc(sizeof(*new_entry), "Socket entry");
+
+  new_entry->fd = fd;
+  new_entry->process_immediate = pf_imm;
+  new_entry->data = data;
+  new_entry->flags = flags;
+
+  /* Queue */
+  list_add_before(&socket_head, &new_entry->socket_node);
+}
+
+/**
+ * Remove a socket and handler to the socketset
+ * beeing used in the main select(2) loop
+ * in listen_loop
+ *
+ *@param fd the socket
+ *@param pf the processing function
+ */
+int
+olsr_socket_remove(int fd, socket_handler_func pf_imm)
+{
+  struct olsr_socket_entry *entry, *iterator;
+
+  if (fd < 0 || pf_imm == NULL) {
+    OLSR_WARN(LOG_SCHEDULER, "Bogus socket entry - not processing...");
+    return 0;
+  }
+  OLSR_DEBUG(LOG_SCHEDULER, "Removing OLSR socket entry %d\n", fd);
+
+  OLSR_FOR_ALL_SOCKETS(entry, iterator) {
+    if (entry->fd == fd && entry->process_immediate == pf_imm) {
+      /* just mark this node as "deleted", it will be cleared later at the end of handle_fds() */
+      entry->process_immediate = NULL;
+      entry->flags = 0;
+      return 1;
+    }
+  }
+  return 0;
+}
+
+void
+olsr_socket_enable(int fd, socket_handler_func pf_imm, unsigned int flags)
+{
+  struct olsr_socket_entry *entry, *iterator;
+
+  OLSR_FOR_ALL_SOCKETS(entry, iterator) {
+    if (entry->fd == fd && entry->process_immediate == pf_imm) {
+      entry->flags |= flags;
+    }
+  }
+}
+
+void
+olsr_socket_disable(int fd, socket_handler_func pf_imm, unsigned int flags)
+{
+  struct olsr_socket_entry *entry, *iterator;
+
+  OLSR_FOR_ALL_SOCKETS(entry, iterator) {
+    if (entry->fd == fd && entry->process_immediate == pf_imm) {
+      entry->flags &= ~flags;
+    }
+  }
+}
+
+void
+handle_sockets(uint32_t next_interval)
+{
+  struct olsr_socket_entry *entry, *iterator;
+  struct timeval tvp;
+  int32_t remaining;
+
+  remaining = olsr_timer_getRelative(next_interval);
+  if (remaining <= 0) {
+    /* we are already over the interval */
+    if (list_is_empty(&socket_head)) {
+      /* If there are no registered sockets we do not call select(2) */
+      return;
+    }
+    tvp.tv_sec = 0;
+    tvp.tv_usec = 0;
+  } else {
+    /* we need an absolute time - milliseconds */
+    tvp.tv_sec = remaining / MSEC_PER_SEC;
+    tvp.tv_usec = (remaining % MSEC_PER_SEC) * USEC_PER_MSEC;
+  }
+
+  /* do at least one select */
+  for (;;) {
+    fd_set ibits, obits;
+    int n, hfd = 0, fdsets = 0;
+    FD_ZERO(&ibits);
+    FD_ZERO(&obits);
+
+    /* Adding file-descriptors to FD set */
+    OLSR_FOR_ALL_SOCKETS(entry, iterator) {
+      if (entry->process_immediate == NULL) {
+        continue;
+      }
+      if ((entry->flags & OLSR_SOCKET_READ) != 0) {
+        fdsets |= OLSR_SOCKET_READ;
+        FD_SET((unsigned int)entry->fd, &ibits);        /* And we cast here since we get a warning on Win32 */
+      }
+      if ((entry->flags & OLSR_SOCKETPOLL_WRITE) != 0) {
+        fdsets |= OLSR_SOCKETPOLL_WRITE;
+        FD_SET((unsigned int)entry->fd, &obits);        /* And we cast here since we get a warning on Win32 */
+      }
+      if ((entry->flags & (OLSR_SOCKET_READ | OLSR_SOCKETPOLL_WRITE)) != 0 && entry->fd >= hfd) {
+        hfd = entry->fd + 1;
+      }
+    }
+
+    if (hfd == 0 && (long)remaining <= 0) {
+      /* we are over the interval and we have no fd's. Skip the select() etc. */
+      return;
+    }
+
+    do {
+      n = os_select(hfd, fdsets & OLSR_SOCKET_READ ? &ibits : NULL, fdsets & OLSR_SOCKETPOLL_WRITE ? &obits : NULL, NULL, &tvp);
+    } while (n == -1 && errno == EINTR);
+
+    if (n == 0) {               /* timeout! */
+      break;
+    }
+    if (n == -1) {              /* Did something go wrong? */
+      OLSR_WARN(LOG_SCHEDULER, "select error: %s", strerror(errno));
+      break;
+    }
+
+    /* Update time since this is much used by the parsing functions */
+    olsr_timer_updateClock();
+    OLSR_FOR_ALL_SOCKETS(entry, iterator) {
+      int flags;
+      if (entry->process_immediate == NULL) {
+        continue;
+      }
+      flags = 0;
+      if (FD_ISSET(entry->fd, &ibits)) {
+        flags |= OLSR_SOCKET_READ;
+      }
+      if (FD_ISSET(entry->fd, &obits)) {
+        flags |= OLSR_SOCKETPOLL_WRITE;
+      }
+      if (flags != 0) {
+        entry->process_immediate(entry->fd, entry->data, flags);
+      }
+    }
+
+    /* calculate the next timeout */
+    remaining = olsr_timer_getRelative(next_interval);
+    if (remaining <= 0) {
+      /* we are already over the interval */
+      break;
+    }
+    /* we need an absolute time - milliseconds */
+    tvp.tv_sec = remaining / MSEC_PER_SEC;
+    tvp.tv_usec = (remaining % MSEC_PER_SEC) * USEC_PER_MSEC;
+  }
+
+  OLSR_FOR_ALL_SOCKETS(entry, iterator) {
+    if (entry->process_immediate == NULL) {
+      /* clean up socket handler */
+      list_remove(&entry->socket_node);
+      free(entry);
+    }
+  }
+}
+
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * End:
+ */
similarity index 53%
rename from src/scheduler.h
rename to src/olsr_socket.h
index 3c1b555..5f768b8 100644 (file)
 
 #include "olsr_types.h"
 
-#include <time.h>
-
-#define TIMER_WHEEL_SLOTS 1024
-#define TIMER_WHEEL_MASK (TIMER_WHEEL_SLOTS - 1)
-
-/* prototype for timer callback */
-typedef void (*timer_cb_func) (void *);
-
-/*
- * This struct defines a class of timers which have the same
- * type (periodic/non-periodic) and callback.
- */
-struct olsr_timer_info {
-  /* node of timerinfo tree */
-  struct avl_node node;
-
-  /* name of this timer class */
-  char *name;
-
-  /* callback function */
-  timer_cb_func callback;
-
-  /* true if this is a class of periodic timers */
-  bool periodic;
-
-  /* Stats, resource usage */
-  uint32_t usage;
-
-  /* Stats, resource churn */
-  uint32_t changes;
-};
-
-
-/*
- * Our timer implementation is a based on individual timers arranged in
- * a double linked list hanging of hash containers called a timer wheel slot.
- * For every timer a olsr_timer_entry is created and attached to the timer wheel slot.
- * When the timer fires, the timer_cb function is called with the
- * context pointer.
- */
-struct olsr_timer_entry {
-  /* Wheel membership */
-  struct list_entity timer_list;
-
-  /* backpointer to timer info */
-  struct olsr_timer_info *timer_info;
-
-  /* when timer shall fire (absolute internal timerstamp) */
-  uint32_t timer_clock;
-
-  /* timeperiod between two timer events for periodical timers */
-  uint32_t timer_period;
-
-  /* the jitter expressed in percent */
-  uint8_t timer_jitter_pct;
-
-  /* true if timer is running at the moment */
-  bool timer_running;
-
-  /* true if timer is in callback at the moment */
-  bool timer_in_callback;
-
-  /* cache random() result for performance reasons */
-  unsigned int timer_random;
-
-  /* context pointer */
-  void *timer_cb_context;
-};
-
-/* Timers */
-extern struct avl_tree EXPORT(timerinfo_tree);
-#define OLSR_FOR_ALL_TIMERS(ti, iterator) avl_for_each_element_safe(&timerinfo_tree, ti, node, iterator)
-
-void olsr_init_timers(void);
-void olsr_flush_timers(void);
-
-uint32_t EXPORT(olsr_timer_getAbsolute) (uint32_t relative);
-int32_t EXPORT(olsr_timer_getRelative) (uint32_t absolute);
-bool EXPORT(olsr_timer_isTimedOut) (uint32_t s);
-
-/**
- * Calculates the current time in the internal OLSR representation
- * @return current time
- */
-static inline uint32_t olsr_timer_getNow(void) {
-  return olsr_timer_getAbsolute(0);
-}
-
-void EXPORT(olsr_timer_set) (struct olsr_timer_entry **, uint32_t, uint8_t,
-    void *, struct olsr_timer_info *);
-struct olsr_timer_entry *EXPORT(olsr_timer_start) (uint32_t, uint8_t,
-    void *, struct olsr_timer_info *);
-void EXPORT(olsr_timer_change)(struct olsr_timer_entry *, uint32_t, uint8_t);
-void EXPORT(olsr_timer_stop) (struct olsr_timer_entry *);
-
-struct olsr_timer_info *EXPORT(olsr_timer_add)(const char *name, timer_cb_func callback, bool periodic);
-
-/* Printing timestamps */
-const char *EXPORT(olsr_timer_getClockString)(uint32_t);
-const char *EXPORT(olsr_timer_getWallclockString)(void);
-
-/* Main scheduler loop */
-void olsr_scheduler(void);
-
 /* flags for socket handler */
 static const unsigned int OLSR_SOCKET_READ = 0x04;
 static const unsigned int OLSR_SOCKETPOLL_WRITE = 0x08;
@@ -182,6 +78,7 @@ struct olsr_socket_entry {
 extern struct list_entity EXPORT(socket_head);
 #define OLSR_FOR_ALL_SOCKETS(socket, iterator) list_for_each_element_safe(&socket_head, socket, socket_node, iterator)
 
+void olsr_socket_init(void);
 void olsr_socket_cleanup(void);
 
 void EXPORT(olsr_socket_add) (int fd, socket_handler_func pf_imm, void *data, unsigned int flags);
@@ -190,6 +87,8 @@ int EXPORT(olsr_socket_remove) (int fd, socket_handler_func pf_imm);
 void EXPORT(olsr_socket_enable) (int fd, socket_handler_func pf_imm, unsigned int flags);
 void EXPORT(olsr_socket_disable) (int fd, socket_handler_func pf_imm, unsigned int flags);
 
+void handle_sockets(uint32_t next_interval);
+
 #endif
 
 /*
similarity index 67%
rename from src/scheduler.c
rename to src/olsr_timer.c
index c1dcc2e..56ea36d 100644 (file)
@@ -1,42 +1,8 @@
-
 /*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in
- *   the documentation and/or other materials provided with the
- *   distribution.
- * * Neither the name of olsr.org, olsrd nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * Visit http://www.olsr.org for more information.
- *
- * If you find this software useful feel free to make a donation
- * to the project. For more information see the website or contact
- * the copyright holders.
+ * olsr_timer.c
  *
+ *  Created on: Feb 14, 2011
+ *      Author: rogge
  */
 
 #include <unistd.h>
 
 #include "common/avl.h"
 #include "common/avl_olsr_comp.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "link_set.h"
 #include "olsr.h"
 #include "olsr_memcookie.h"
-#include "os_net.h"
 #include "os_time.h"
 #include "olsr_logging.h"
+#include "olsr_timer.h"
 
 /* Timer data */
 static uint32_t now_times;             /* relative time compared to startup (in milliseconds */
@@ -67,22 +34,12 @@ struct avl_tree timerinfo_tree;
 static struct olsr_memcookie_info *timer_mem_cookie = NULL;
 static struct olsr_memcookie_info *timerinfo_cookie = NULL;
 
-/* Head of all OLSR used sockets */
-struct list_entity socket_head;
-
 /* Prototypes */
 static void walk_timers(uint32_t *);
 static uint32_t calc_jitter(unsigned int rel_time, uint8_t jitter_pct, unsigned int random_val);
 
-/*
- * A wrapper around times(2). Note, that this function has some
- * portability problems, so do not rely on absolute values returned.
- * Under Linux, uclibc and libc directly call the sys_times() located
- * in kernel/sys.c and will only return an error if the tms_buf is
- * not writeable.
- */
-static uint32_t
-olsr_times(void)
+void
+olsr_timer_updateClock(void)
 {
   struct timeval tv;
   uint32_t t;
@@ -110,10 +67,10 @@ olsr_times(void)
       first_tv.tv_usec += 1000000;
     }
     last_tv = tv;
-    return t;
+    now_times =  t;
   }
   last_tv = tv;
-  return (tv.tv_sec - first_tv.tv_sec) * 1000 + (tv.tv_usec - first_tv.tv_usec) / 1000;
+  now_times = (tv.tv_sec - first_tv.tv_sec) * 1000 + (tv.tv_usec - first_tv.tv_usec) / 1000;
 }
 
 /**
@@ -175,211 +132,6 @@ olsr_timer_add(const char *name, timer_cb_func callback, bool periodic) {
   return ti;
 }
 
-/**
- * Add a socket and handler to the socketset
- * beeing used in the main select(2) loop
- * in listen_loop
- *
- *@param fd the socket
- *@param pf the processing function
- */
-void
-olsr_socket_add(int fd, socket_handler_func pf_imm, void *data, unsigned int flags)
-{
-  struct olsr_socket_entry *new_entry;
-
-  if (fd < 0 || pf_imm == NULL) {
-    OLSR_WARN(LOG_SCHEDULER, "Bogus socket entry - not registering...");
-    return;
-  }
-  OLSR_DEBUG(LOG_SCHEDULER, "Adding OLSR socket entry %d\n", fd);
-
-  new_entry = olsr_malloc(sizeof(*new_entry), "Socket entry");
-
-  new_entry->fd = fd;
-  new_entry->process_immediate = pf_imm;
-  new_entry->data = data;
-  new_entry->flags = flags;
-
-  /* Queue */
-  list_add_before(&socket_head, &new_entry->socket_node);
-}
-
-/**
- * Remove a socket and handler to the socketset
- * beeing used in the main select(2) loop
- * in listen_loop
- *
- *@param fd the socket
- *@param pf the processing function
- */
-int
-olsr_socket_remove(int fd, socket_handler_func pf_imm)
-{
-  struct olsr_socket_entry *entry, *iterator;
-
-  if (fd < 0 || pf_imm == NULL) {
-    OLSR_WARN(LOG_SCHEDULER, "Bogus socket entry - not processing...");
-    return 0;
-  }
-  OLSR_DEBUG(LOG_SCHEDULER, "Removing OLSR socket entry %d\n", fd);
-
-  OLSR_FOR_ALL_SOCKETS(entry, iterator) {
-    if (entry->fd == fd && entry->process_immediate == pf_imm) {
-      /* just mark this node as "deleted", it will be cleared later at the end of handle_fds() */
-      entry->process_immediate = NULL;
-      entry->flags = 0;
-      return 1;
-    }
-  }
-  return 0;
-}
-
-void
-olsr_socket_enable(int fd, socket_handler_func pf_imm, unsigned int flags)
-{
-  struct olsr_socket_entry *entry, *iterator;
-
-  OLSR_FOR_ALL_SOCKETS(entry, iterator) {
-    if (entry->fd == fd && entry->process_immediate == pf_imm) {
-      entry->flags |= flags;
-    }
-  }
-}
-
-void
-olsr_socket_disable(int fd, socket_handler_func pf_imm, unsigned int flags)
-{
-  struct olsr_socket_entry *entry, *iterator;
-
-  OLSR_FOR_ALL_SOCKETS(entry, iterator) {
-    if (entry->fd == fd && entry->process_immediate == pf_imm) {
-      entry->flags &= ~flags;
-    }
-  }
-}
-
-/**
- * Close and free all sockets.
- */
-void
-olsr_socket_cleanup(void)
-{
-  struct olsr_socket_entry *entry, *iterator;
-
-  OLSR_FOR_ALL_SOCKETS(entry, iterator) {
-    os_close(entry->fd);
-    list_remove(&entry->socket_node);
-    free(entry);
-  }
-}
-
-static void
-handle_fds(uint32_t next_interval)
-{
-  struct olsr_socket_entry *entry, *iterator;
-  struct timeval tvp;
-  int32_t remaining;
-
-  /* calculate the first timeout */
-  now_times = olsr_times();
-
-  remaining = olsr_timer_getRelative(next_interval);
-  if (remaining <= 0) {
-    /* we are already over the interval */
-    if (list_is_empty(&socket_head)) {
-      /* If there are no registered sockets we do not call select(2) */
-      return;
-    }
-    tvp.tv_sec = 0;
-    tvp.tv_usec = 0;
-  } else {
-    /* we need an absolute time - milliseconds */
-    tvp.tv_sec = remaining / MSEC_PER_SEC;
-    tvp.tv_usec = (remaining % MSEC_PER_SEC) * USEC_PER_MSEC;
-  }
-
-  /* do at least one select */
-  for (;;) {
-    fd_set ibits, obits;
-    int n, hfd = 0, fdsets = 0;
-    FD_ZERO(&ibits);
-    FD_ZERO(&obits);
-
-    /* Adding file-descriptors to FD set */
-    OLSR_FOR_ALL_SOCKETS(entry, iterator) {
-      if (entry->process_immediate == NULL) {
-        continue;
-      }
-      if ((entry->flags & OLSR_SOCKET_READ) != 0) {
-        fdsets |= OLSR_SOCKET_READ;
-        FD_SET((unsigned int)entry->fd, &ibits);        /* And we cast here since we get a warning on Win32 */
-      }
-      if ((entry->flags & OLSR_SOCKETPOLL_WRITE) != 0) {
-        fdsets |= OLSR_SOCKETPOLL_WRITE;
-        FD_SET((unsigned int)entry->fd, &obits);        /* And we cast here since we get a warning on Win32 */
-      }
-      if ((entry->flags & (OLSR_SOCKET_READ | OLSR_SOCKETPOLL_WRITE)) != 0 && entry->fd >= hfd) {
-        hfd = entry->fd + 1;
-      }
-    }
-
-    if (hfd == 0 && (long)remaining <= 0) {
-      /* we are over the interval and we have no fd's. Skip the select() etc. */
-      return;
-    }
-
-    do {
-      n = os_select(hfd, fdsets & OLSR_SOCKET_READ ? &ibits : NULL, fdsets & OLSR_SOCKETPOLL_WRITE ? &obits : NULL, NULL, &tvp);
-    } while (n == -1 && errno == EINTR);
-
-    if (n == 0) {               /* timeout! */
-      break;
-    }
-    if (n == -1) {              /* Did something go wrong? */
-      OLSR_WARN(LOG_SCHEDULER, "select error: %s", strerror(errno));
-      break;
-    }
-
-    /* Update time since this is much used by the parsing functions */
-    now_times = olsr_times();
-    OLSR_FOR_ALL_SOCKETS(entry, iterator) {
-      int flags;
-      if (entry->process_immediate == NULL) {
-        continue;
-      }
-      flags = 0;
-      if (FD_ISSET(entry->fd, &ibits)) {
-        flags |= OLSR_SOCKET_READ;
-      }
-      if (FD_ISSET(entry->fd, &obits)) {
-        flags |= OLSR_SOCKETPOLL_WRITE;
-      }
-      if (flags != 0) {
-        entry->process_immediate(entry->fd, entry->data, flags);
-      }
-    }
-
-    /* calculate the next timeout */
-    remaining = olsr_timer_getRelative(next_interval);
-    if (remaining <= 0) {
-      /* we are already over the interval */
-      break;
-    }
-    /* we need an absolute time - milliseconds */
-    tvp.tv_sec = remaining / MSEC_PER_SEC;
-    tvp.tv_usec = (remaining % MSEC_PER_SEC) * USEC_PER_MSEC;
-  }
-
-  OLSR_FOR_ALL_SOCKETS(entry, iterator) {
-    if (entry->process_immediate == NULL) {
-      /* clean up socket handler */
-      list_remove(&entry->socket_node);
-      free(entry);
-    }
-  }
-}
-
 /**
  * Main scheduler event loop. Polls at every
  * sched_poll_interval and calls all functions
@@ -390,7 +142,7 @@ handle_fds(uint32_t next_interval)
  * @return nada
  */
 void
-olsr_scheduler(void)
+olsr_timer_scheduler(void)
 {
   OLSR_INFO(LOG_SCHEDULER, "Scheduler started - polling every %u ms\n", olsr_cnf->pollrate);
 
@@ -402,7 +154,7 @@ olsr_scheduler(void)
      * Update the global timestamp. We are using a non-wallclock timer here
      * to avoid any undesired side effects if the system clock changes.
      */
-    now_times = olsr_times();
+    olsr_timer_updateClock();
     next_interval = olsr_timer_getAbsolute(olsr_cnf->pollrate);
 
     /* Process timers */
@@ -418,8 +170,14 @@ olsr_scheduler(void)
       link_changes = false;
     }
 
+    /*
+     * Update the global timestamp. We are using a non-wallclock timer here
+     * to avoid any undesired side effects if the system clock changes.
+     */
+    olsr_timer_updateClock();
+
     /* Read incoming data and handle it immediately */
-    handle_fds(next_interval);
+    handle_sockets(next_interval);
   }
 }
 
@@ -459,7 +217,7 @@ calc_jitter(unsigned int rel_time, uint8_t jitter_pct, unsigned int random_val)
  * Init datastructures for maintaining timers.
  */
 void
-olsr_init_timers(void)
+olsr_timer_init(void)
 {
   int idx;
 
@@ -471,7 +229,7 @@ olsr_init_timers(void)
     olsr_exit(1);
   }
   last_tv = first_tv;
-  now_times = olsr_times();
+  olsr_timer_updateClock();
 
   /* init lists */
   list_init_head(&socket_head);
@@ -601,7 +359,7 @@ walk_timers(uint32_t * last_run)
  * Stop and delete all timers.
  */
 void
-olsr_flush_timers(void)
+olsr_timer_cleanup(void)
 {
   struct olsr_timer_info *ti, *iterator;
 
@@ -859,10 +617,3 @@ olsr_timer_set(struct olsr_timer_entry **timer_ptr,
     olsr_timer_change(*timer_ptr, rel_time, jitter_pct);
   }
 }
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * End:
- */
diff --git a/src/olsr_timer.h b/src/olsr_timer.h
new file mode 100644 (file)
index 0000000..469b4a1
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * olsr_timer.h
+ *
+ *  Created on: Feb 14, 2011
+ *      Author: rogge
+ */
+
+#ifndef OLSR_TIMER_H_
+#define OLSR_TIMER_H_
+
+#include "olsr_time.h"
+#include "common/list.h"
+#include "common/avl.h"
+
+#include "olsr_types.h"
+
+#define TIMER_WHEEL_SLOTS 1024
+#define TIMER_WHEEL_MASK (TIMER_WHEEL_SLOTS - 1)
+
+/* prototype for timer callback */
+typedef void (*timer_cb_func) (void *);
+
+/*
+ * This struct defines a class of timers which have the same
+ * type (periodic/non-periodic) and callback.
+ */
+struct olsr_timer_info {
+  /* node of timerinfo tree */
+  struct avl_node node;
+
+  /* name of this timer class */
+  char *name;
+
+  /* callback function */
+  timer_cb_func callback;
+
+  /* true if this is a class of periodic timers */
+  bool periodic;
+
+  /* Stats, resource usage */
+  uint32_t usage;
+
+  /* Stats, resource churn */
+  uint32_t changes;
+};
+
+
+/*
+ * Our timer implementation is a based on individual timers arranged in
+ * a double linked list hanging of hash containers called a timer wheel slot.
+ * For every timer a olsr_timer_entry is created and attached to the timer wheel slot.
+ * When the timer fires, the timer_cb function is called with the
+ * context pointer.
+ */
+struct olsr_timer_entry {
+  /* Wheel membership */
+  struct list_entity timer_list;
+
+  /* backpointer to timer info */
+  struct olsr_timer_info *timer_info;
+
+  /* when timer shall fire (absolute internal timerstamp) */
+  uint32_t timer_clock;
+
+  /* timeperiod between two timer events for periodical timers */
+  uint32_t timer_period;
+
+  /* the jitter expressed in percent */
+  uint8_t timer_jitter_pct;
+
+  /* true if timer is running at the moment */
+  bool timer_running;
+
+  /* true if timer is in callback at the moment */
+  bool timer_in_callback;
+
+  /* cache random() result for performance reasons */
+  unsigned int timer_random;
+
+  /* context pointer */
+  void *timer_cb_context;
+};
+
+/* Timers */
+extern struct avl_tree EXPORT(timerinfo_tree);
+#define OLSR_FOR_ALL_TIMERS(ti, iterator) avl_for_each_element_safe(&timerinfo_tree, ti, node, iterator)
+
+void olsr_timer_init(void);
+void olsr_timer_cleanup(void);
+void olsr_timer_updateClock(void);
+
+uint32_t EXPORT(olsr_timer_getAbsolute) (uint32_t relative);
+int32_t EXPORT(olsr_timer_getRelative) (uint32_t absolute);
+bool EXPORT(olsr_timer_isTimedOut) (uint32_t s);
+
+/**
+ * Calculates the current time in the internal OLSR representation
+ * @return current time
+ */
+static inline uint32_t olsr_timer_getNow(void) {
+  return olsr_timer_getAbsolute(0);
+}
+
+void EXPORT(olsr_timer_set) (struct olsr_timer_entry **, uint32_t, uint8_t,
+    void *, struct olsr_timer_info *);
+struct olsr_timer_entry *EXPORT(olsr_timer_start) (uint32_t, uint8_t,
+    void *, struct olsr_timer_info *);
+void EXPORT(olsr_timer_change)(struct olsr_timer_entry *, uint32_t, uint8_t);
+void EXPORT(olsr_timer_stop) (struct olsr_timer_entry *);
+
+struct olsr_timer_info *EXPORT(olsr_timer_add)(const char *name, timer_cb_func callback, bool periodic);
+
+const char *EXPORT(olsr_timer_getClockString)(uint32_t);
+const char *EXPORT(olsr_timer_getWallclockString)(void);
+
+/* Main scheduler loop */
+void olsr_timer_scheduler(void);
+
+#endif /* OLSR_TIMER_H_ */
index 2a69e2d..be5dc27 100644 (file)
@@ -46,7 +46,8 @@
 #include "common/list.h"
 #include "olsr_protocol.h"
 #include "lq_packet.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr_memcookie.h"
 #include "duplicate_set.h"
 
index cbb62bc..97e08b6 100644 (file)
@@ -51,7 +51,8 @@
 #include "os_net.h"
 #include "net_olsr.h"
 #include "parser.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr_time.h"
 #include "lq_packet.h"
 #include "link_set.h"
index d59dc07..dac21f9 100644 (file)
@@ -47,7 +47,8 @@
 #include "parser.h"
 #include "defs.h"
 #include "os_net.h"
-#include "scheduler.h"
+#include "olsr_timer.h"
+#include "olsr_socket.h"
 #include "olsr_time.h"
 #include "lq_packet.h"
 #include "net_olsr.h"