[pisa-src] r1227 - in trunk: include/scheduler.h libpisa/scheduler.c pisacd/cdctx.c pisacd/cdctx.h pisacd/cdmain.c pisasd/sdctx.c pisasd/sdctx.h pisasd/sdmain.c

  • From: Thomas Jansen <mithi@xxxxxxxxx>
  • To: pisa-src@xxxxxxxxxxxxx
  • Date: Mon, 19 Oct 2009 12:49:07 +0200

Author: tjansen
Date: Mon Oct 19 12:49:07 2009
New Revision: 1227

Log:
Scheduler switched from flag signaling to pipe signaling.

This allows us to have immediate reactions in an idle system, as we don't wait
until the select call reached the timeout. We also don't wake up periodically
on idle systems unless the scheduler has things to do.

Modified:
   trunk/include/scheduler.h
   trunk/libpisa/scheduler.c
   trunk/pisacd/cdctx.c
   trunk/pisacd/cdctx.h
   trunk/pisacd/cdmain.c
   trunk/pisasd/sdctx.c
   trunk/pisasd/sdctx.h
   trunk/pisasd/sdmain.c

Modified: trunk/include/scheduler.h
==============================================================================
--- trunk/include/scheduler.h   Mon Oct 19 11:51:36 2009        (r1226)
+++ trunk/include/scheduler.h   Mon Oct 19 12:49:07 2009        (r1227)
@@ -27,7 +27,7 @@
        struct pisa_sched_task *next;
 } pisa_sched_task;
 
-void pisa_sched_init(int *shared);
+void pisa_sched_init(int *p);
 void pisa_sched_cleanup(void);
 void pisa_sched_run(void);
 

Modified: trunk/libpisa/scheduler.c
==============================================================================
--- trunk/libpisa/scheduler.c   Mon Oct 19 11:51:36 2009        (r1226)
+++ trunk/libpisa/scheduler.c   Mon Oct 19 12:49:07 2009        (r1227)
@@ -17,10 +17,10 @@
 #include "util.h"
 
 /**
- * Our way to tell the main loop that we want to be called is setting the
- * shared variable to a value != 0
+ * Our way to tell the main loop that we want to be called is writing a byte
+ * to the pipe.
  */
-static int *flag = NULL;
+static int pipe_main = 0;
 
 /**
  * Our thread ID for the scheduler thread
@@ -69,12 +69,11 @@
                        /* At least the first action is due now, raise the
                         * flag. As we have to reschedule afterwards, sleep
                         * for a _long_ time. We don't care about tv_usec. */
-                       *flag = 1;
+                       write(pipe_main, "1", 1);
                        timeout.tv_sec = 1000000;
                } else {
                        /* No action is due now, sleep until the head is due
                         * or we are woken up for rescheduling. */
-                       *flag = 0;
                        if (head)
                                timersub(&head->due, &now, &timeout);
                        else
@@ -90,17 +89,20 @@
  * Initialize the scheduler. Create a thread that sleeps until the first
  * element in the list is due.
  *
- * @param shared pointer to the variable shared with the main thread
+ * @param p pipe to the main thread
  */ 
-void pisa_sched_init(int *shared)
+void pisa_sched_init(int *p)
 {
        int result;
 
-       flag = shared;
+       result = pipe(p);
+       if (result != 0)
+               PISA_ERROR("Could not create external pipe for scheduler.\n");
+       pipe_main = p[1];
 
        result = pipe(pipe_sched);
        if (result != 0)
-               PISA_ERROR("Could not create pipe for scheduler.\n");
+               PISA_ERROR("Could not create internal pipe for scheduler.\n");
 
        result = pthread_mutex_init(&mutex_list, NULL);
        if (result != 0)
@@ -112,8 +114,7 @@
 }
 
 /**
- * Clean up the scheduler. Free the task list, clear the scheduler flag and
- * kill the thread.
+ * Clean up the scheduler. Free the task list and kill the thread.
  */
 void pisa_sched_cleanup(void)
 {
@@ -127,8 +128,6 @@
 
        while (head)
                pisa_sched_remove(head);
-
-       *flag = 0;
 }
 
 /**
@@ -157,8 +156,7 @@
 
 /**
  * Run scheduled actions. Called by the main thread eventually if we set the
- * shared variable to a value != 0. Handle all actions that are due and reset
- * the shared variable.
+ * shared variable to a value != 0. Handle all actions that are due.
  */
 void pisa_sched_run(void)
 {
@@ -193,7 +191,6 @@
                free(tmp);
        }
 
-       *flag = 0;
        write(pipe_sched[1], "0", 1);
 }
 

Modified: trunk/pisacd/cdctx.c
==============================================================================
--- trunk/pisacd/cdctx.c        Mon Oct 19 11:51:36 2009        (r1226)
+++ trunk/pisacd/cdctx.c        Mon Oct 19 12:49:07 2009        (r1227)
@@ -80,7 +80,8 @@
        cdctx->natlist = NULL;
        cdctx->conlist = NULL;
 
-       cdctx->scheduler = 0;
+       cdctx->fd_scheduler[0] = -1;
+       cdctx->fd_scheduler[1] = -1;
 }
 
 /**

Modified: trunk/pisacd/cdctx.h
==============================================================================
--- trunk/pisacd/cdctx.h        Mon Oct 19 11:51:36 2009        (r1226)
+++ trunk/pisacd/cdctx.h        Mon Oct 19 12:49:07 2009        (r1227)
@@ -138,9 +138,9 @@
        pisa_conmgr_list *conlist;
 
        /**
-        * 0 if the scheduler has nothing to do, != 0 otherwise
+        * Pipe used by the scheduler to signal that an action is ready.
         */
-       int scheduler;
+       int fd_scheduler[2];
 } cd_context;
 
 extern cd_context cd_ctx;

Modified: trunk/pisacd/cdmain.c
==============================================================================
--- trunk/pisacd/cdmain.c       Mon Oct 19 11:51:36 2009        (r1226)
+++ trunk/pisacd/cdmain.c       Mon Oct 19 12:49:07 2009        (r1227)
@@ -276,7 +276,7 @@
        pisa_tunnel_configure_main(cd_ctx.ifname_tunnel, &cd_cfg.local_ipv4, 
&cd_cfg.local_netmask, MTU_TUN);
 
        /* Initialize the scheduler and start some maintenance tasks */
-       pisa_sched_init(&cd_ctx.scheduler);
+       pisa_sched_init(cd_ctx.fd_scheduler);
        pisa_sched_add_now(pisa_task_heartbeat, NULL);
        pisa_sched_add_now(pisa_task_pending, NULL);
        if (cd_cfg.idle_disconnect_delay > 0)
@@ -305,6 +305,8 @@
        close(cd_ctx.tunc);
        close(cd_ctx.tund);
        close(cd_ctx.tunnel);
+       close(cd_ctx.fd_scheduler[0]);
+       close(cd_ctx.fd_scheduler[1]);
 
        pisa_ctrlhandler_cleanup(&cd_ctx.ctrlhandlers);
 
@@ -317,6 +319,17 @@
 }
 
 /**
+ * The scheduler signaled that something must be handled. Read the byte from
+ * the pipe and run the scheduled task.
+ */
+static inline void pisa_handle_scheduler(void)
+{
+       char c;
+       read(cd_ctx.fd_scheduler[0], &c, 1);
+       pisa_sched_run();
+}
+
+/**
  * The core loop as a client daemon.
  * All message processing happens here.
  * This function takes care of adding all relevant file descriptors to
@@ -327,7 +340,6 @@
 {
        struct sockaddr_in      from_addr;
        int                     maxfd = 0;
-       struct timeval          select_to;
        int                     ret = 0;
        int                     pending = 0;
        fd_set                  readfds;
@@ -348,9 +360,6 @@
                int     start_alarm = FALSE;
 #endif /* REMOVE_PREAUTH_CODE */
 
-               select_to.tv_sec  = 1;
-               select_to.tv_usec = 0;
-
                /* sockets.tunnel needs to be always included in the reading fd 
list */
                FD_ZERO(&readfds);
                FD_SET(cd_ctx.tunnel, &readfds);
@@ -361,6 +370,7 @@
                FD_SET(cd_ctx.fd_pasrv, &readfds);
 #endif /* REMOVE_PREAUTH_CODE */
                FD_SET(cd_ctx.fd_pisaconf, &readfds);
+               FD_SET(cd_ctx.fd_scheduler[0], &readfds);
 
 #ifdef REMOVE_PREAUTH_CODE
                /* Send periodical neighbor exchange requests,
@@ -382,7 +392,7 @@
                 * Inline once PREAUTH is gone. -- Thomas */
                maxfd = cd_get_maxfd();
 
-               if ((ret = select(maxfd + 1, &readfds, NULL, NULL, &select_to)) 
<= 0) {
+               if ((ret = select(maxfd + 1, &readfds, NULL, NULL, NULL)) <= 0) 
{
 #ifdef REMOVE_PREAUTH_CODE
                        if (cd_ctx.is_cd_running) {
                                if (cd_ctx.is_scanning) {
@@ -435,6 +445,9 @@
 
                        if (FD_ISSET(cd_ctx.fd_pisaconf, &readfds))
                                pisa_conf_handle_packet(cd_ctx.fd_pisaconf);
+
+                       if (FD_ISSET(cd_ctx.fd_scheduler[0], &readfds))
+                               pisa_handle_scheduler();
                }
 
 #ifdef REMOVE_PREAUTH_CODE
@@ -447,9 +460,6 @@
                        cd_start_alarm();
                }
 #endif /* REMOVE_PREAUTH_CODE */
-
-               if (cd_ctx.scheduler)
-                       pisa_sched_run();
        }
 }
 
@@ -926,15 +936,16 @@
 #endif /* REMOVE_PREAUTH_CODE */
        tmfd = pisa_maxInt(tmfd, cd_ctx.tunc);
        tmfd = pisa_maxInt(tmfd, cd_ctx.tund);
+       tmfd = pisa_maxInt(tmfd, cd_ctx.fd_scheduler[0]);
        maxfd = tmfd + 1;
 #else
 #ifdef REMOVE_PREAUTH_CODE
-       maxfd = pisa_maxof(6, cd_ctx.tunnel, cd_ctx.fd_pisaconf,
+       maxfd = pisa_maxof(7, cd_ctx.tunnel, cd_ctx.fd_pisaconf,
                cd_ctx.fd_pacli, cd_ctx.fd_pasrv,
-               cd_ctx.tunc, cd_ctx.tund) + 1;
+               cd_ctx.tunc, cd_ctx.tund, cd_ctx.fd_scheduler[0]) + 1;
 #else 
-       maxfd = pisa_maxof(4, cd_ctx.tunnel, cd_ctx.fd_pisaconf,
-               cd_ctx.tunc, cd_ctx.tund) + 1;
+       maxfd = pisa_maxof(5, cd_ctx.tunnel, cd_ctx.fd_pisaconf,
+               cd_ctx.tunc, cd_ctx.tund, cd_ctx.fd_scheduler[0]) + 1;
 #endif /* REMOVE_PREAUTH_CODE */
 #endif
 

Modified: trunk/pisasd/sdctx.c
==============================================================================
--- trunk/pisasd/sdctx.c        Mon Oct 19 11:51:36 2009        (r1226)
+++ trunk/pisasd/sdctx.c        Mon Oct 19 12:49:07 2009        (r1227)
@@ -67,7 +67,8 @@
        sdctx->conlist = NULL;
        sdctx->disable_ip4_forward=0;
 
-       sdctx->scheduler = 0;
+       sdctx->fd_scheduler[0] = -1;
+       sdctx->fd_scheduler[1] = -1;
 }
 
 /**

Modified: trunk/pisasd/sdctx.h
==============================================================================
--- trunk/pisasd/sdctx.h        Mon Oct 19 11:51:36 2009        (r1226)
+++ trunk/pisasd/sdctx.h        Mon Oct 19 12:49:07 2009        (r1227)
@@ -126,9 +126,9 @@
        int disable_ip4_forward;
 
        /**
-        * 0 if the scheduler has nothing to do, != 0 otherwise
+        * Pipe used by the scheduler to signal that an action is ready.
         */
-       int scheduler;
+       int fd_scheduler[2];
 } sd_context;
 
 extern sd_context sd_ctx;

Modified: trunk/pisasd/sdmain.c
==============================================================================
--- trunk/pisasd/sdmain.c       Mon Oct 19 11:51:36 2009        (r1226)
+++ trunk/pisasd/sdmain.c       Mon Oct 19 12:49:07 2009        (r1227)
@@ -250,7 +250,7 @@
        pisa_tunnel_configure_main(sd_ctx.fd_pisa_tunnel_name, &sd_cfg.ipaddr, 
&netmask, MTU_TUN);
 
        /* Initialize the scheduler */
-       pisa_sched_init(&sd_ctx.scheduler);
+       pisa_sched_init(sd_ctx.fd_scheduler);
 }
 
 /**
@@ -284,6 +284,8 @@
 #endif /* REMOVE_PREAUTH_CODE */
        close(sd_ctx.tunnel);
        close(sd_ctx.fd_pisaconf);
+       close(sd_ctx.fd_scheduler[0]);
+       close(sd_ctx.fd_scheduler[1]);
 
        /* Disable IPv4 forwarding */
        pisa_forwarding_stop();
@@ -301,6 +303,17 @@
 }
 
 /**
+ * The scheduler signaled that something must be handled. Read the byte from
+ * the pipe and run the scheduled task.
+ */
+static inline void pisa_handle_scheduler(void)
+{
+       char c;
+       read(sd_ctx.fd_scheduler[0], &c, 1);
+       pisa_sched_run();
+}
+
+/**
  * The core loop as a server daemon.
  * All message processing happens here.
  * This function takes care of adding all relevant file descriptors to
@@ -317,13 +330,9 @@
        PISA_INFO("\nEntering main loop\n");
 
        while (sd_ctx.is_sd_running) {
-               struct timeval select_to;
                fd_set  readfds;
                int     maxfd = 0;
 
-               select_to.tv_sec  = 1;
-               select_to.tv_usec = 0;
-
                pisa_sd_timeout_collect();
 
                /* Add all sockets to the read set */
@@ -335,21 +344,24 @@
                FD_SET(sd_ctx.fd_pstuns, &readfds);
 #endif /* REMOVE_PREAUTH_CODE */
                FD_SET(sd_ctx.tunnel, &readfds);
-               FD_SET(sd_ctx.fd_pisaconf,&readfds);
+               FD_SET(sd_ctx.fd_pisaconf, &readfds);
+               FD_SET(sd_ctx.fd_scheduler[0], &readfds);
 
 #ifdef REMOVE_PREAUTH_CODE
-               maxfd = 1 + pisa_maxof(6, sd_ctx.tunc, sd_ctx.tund,
+               maxfd = 1 + pisa_maxof(7, sd_ctx.tunc, sd_ctx.tund,
                                        sd_ctx.fd_pstunc, sd_ctx.fd_pstuns,
-                                       sd_ctx.tunnel,sd_ctx.tunnel);
+                                       sd_ctx.tunnel,sd_ctx.tunnel,
+                                       sd_ctx.fd_scheduler[0]);
 #else
                /* Performance optimization: Does this really have to be
                 * recalcutated every time? Check again after PREAUTH is
                 * removed. -- Thomas */
-               maxfd = 1 + pisa_maxof(4, sd_ctx.tunc, sd_ctx.tund,
-                                       sd_ctx.tunnel,sd_ctx.tunnel);
+               maxfd = 1 + pisa_maxof(5, sd_ctx.tunc, sd_ctx.tund,
+                                       sd_ctx.tunnel,sd_ctx.tunnel,
+                                       sd_ctx.fd_scheduler[0]);
 #endif /* REMOVE_PREAUTH_CODE */
 
-               if (select(maxfd + 1, &readfds, NULL, NULL, &select_to) > 0) {
+               if (select(maxfd + 1, &readfds, NULL, NULL, NULL) > 0) {
                        if (FD_ISSET(sd_ctx.tunc, &readfds))
                                pisa_ctrlhandler_dispatch(&sd_ctx.ctrlhandlers, 
sd_ctx.tunc);
 
@@ -366,10 +378,10 @@
 
                        if (FD_ISSET(sd_ctx.fd_pisaconf, &readfds))
                                pisa_conf_handle_packet(sd_ctx.fd_pisaconf);
-               }
 
-               if (sd_ctx.scheduler)
-                       pisa_sched_run();
+                       if (FD_ISSET(sd_ctx.fd_scheduler[0], &readfds))
+                               pisa_handle_scheduler();
+               }
 
 #ifdef REMOVE_PREAUTH_CODE
                sd_start_alarm();

Other related posts:

  • » [pisa-src] r1227 - in trunk: include/scheduler.h libpisa/scheduler.c pisacd/cdctx.c pisacd/cdctx.h pisacd/cdmain.c pisasd/sdctx.c pisasd/sdctx.h pisasd/sdmain.c - Thomas Jansen