]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 't/timing_improvements'
authorAndre Noll <maan@systemlinux.org>
Sat, 13 Aug 2011 10:17:51 +0000 (12:17 +0200)
committerAndre Noll <maan@systemlinux.org>
Sat, 13 Aug 2011 10:18:31 +0000 (12:18 +0200)
1  2 
NEWS
sched.c

diff --combined NEWS
index f76a6e97c1ed9e6d27ddb91a7637b2e550c35fbe,7d330ce48c5528a43156fd7b12833859218e9f1e..49747ccb64326c52f5a3e542c73bf4785dd76953
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -17,8 -17,6 +17,9 @@@ are the highlights of this release
          to replace 5 lines in the config file (one for each audio
          format) by one single line. See the manual for details.
        - Compiles cleanly also with llvm/clang.
 +      - Corrupt mp3 files are handled more gracefully.
 +      - sched: Optimized zero timeouts.
++      - vss timeout cleanups.
  
  --------------------------------------
  0.4.7 (2011-06-01) "infinite rollback"
diff --combined sched.c
index ca365f17e911d13a49688196ecfd1bcfab5d0363,65176bd91a875ab16ce07194299dbc9bde5a00a5..385dde61f0fc210dd52bdb1192b392e39061977b
+++ b/sched.c
@@@ -9,7 -9,6 +9,7 @@@
  #include <regex.h>
  #include <assert.h>
  #include <sys/time.h>
 +#include <stdbool.h>
  
  #include "para.h"
  #include "ipc.h"
@@@ -47,25 -46,24 +47,25 @@@ static void unregister_task(struct tas
                list_del(&t->post_select_node);
  }
  
 +static inline bool timeout_is_zero(struct sched *s)
 +{
 +      struct timeval *tv = &s->select_timeout;
 +      return tv->tv_sec == 0 && tv->tv_usec == 0;
 +}
 +
  static void sched_preselect(struct sched *s)
  {
        struct task *t, *tmp;
        list_for_each_entry_safe(t, tmp, &pre_select_list, pre_select_node) {
 -              if (t->pre_select)
 -                      t->pre_select(s, t);
 -//            PARA_INFO_LOG("%s \n", t->status);
 -              if (t->error >= 0)
 +              if (t->error < 0) {
 +                      unregister_task(t);
                        continue;
 -              /*
 -               * We have to check whether the list is empty because the call
 -               * to ->pre_select() might have called sched_shutdown(). In
 -               * this case t has been unregistered already, so we must not
 -               * unregister it again.
 -               */
 -              if (list_empty(&pre_select_list))
 -                      return;
 -              unregister_task(t);
 +              }
 +              if (!t->pre_select)
 +                      continue;
 +              t->pre_select(s, t);
 +              if (timeout_is_zero(s))
 +                      break;
        }
  }
  
@@@ -99,12 -97,7 +99,12 @@@ static void sched_post_select(struct sc
  //            PARA_INFO_LOG("%s: %d\n", t->status, t->ret);
                if (t->error >= 0)
                        continue;
 -              /* nec., see sched_preselect() */
 +              /*
 +               * We have to check whether the list is empty because the call
 +               * to ->post_select() might have called sched_shutdown(). In
 +               * this case t has been unregistered already, so we must not
 +               * unregister it again.
 +               */
                if (list_empty(&post_select_list))
                        return;
                unregister_task(t);
@@@ -143,23 -136,21 +143,23 @@@ again
        sched_preselect(s);
        if (list_empty(&pre_select_list) && list_empty(&post_select_list))
                return 0;
 -      ret = s->select_function(s->max_fileno + 1, &s->rfds, &s->wfds,
 -              &s->select_timeout);
 -      if (ret < 0)
 -              return ret;
 -      if (ret == 0) {
 -              /*
 -               * APUE: Be careful not to check the descriptor sets on return
 -               * unless the return value is greater than zero. The return
 -               * state of the descriptor sets is implementation dependent if
 -               * either a signal is caught or the timer expires.
 -               */
 -              FD_ZERO(&s->rfds);
 -              FD_ZERO(&s->wfds);
 +      if (!timeout_is_zero(s)) {
 +              ret = s->select_function(s->max_fileno + 1, &s->rfds, &s->wfds,
 +                      &s->select_timeout);
 +              if (ret < 0)
 +                      return ret;
 +              if (ret == 0) {
 +                      /*
 +                       * APUE: Be careful not to check the descriptor sets on return
 +                       * unless the return value is greater than zero. The return
 +                       * state of the descriptor sets is implementation dependent if
 +                       * either a signal is caught or the timer expires.
 +                       */
 +                      FD_ZERO(&s->rfds);
 +                      FD_ZERO(&s->wfds);
 +              }
 +              gettimeofday(now, NULL);
        }
 -      gettimeofday(now, NULL);
        sched_post_select(s);
        if (list_empty(&pre_select_list) && list_empty(&post_select_list))
                return 0;
@@@ -206,8 -197,7 +206,8 @@@ void register_task(struct task *t
   * Unregister all tasks.
   *
   * This will cause \a schedule() to return immediately because both the
 - * \a pre_select_list and the \a post_select_list are empty.
 + * \a pre_select_list and the \a post_select_list are empty. This function
 + * must be called from the post_select (rather than the pre_select) method.
   */
  void sched_shutdown(void)
  {
@@@ -268,7 -258,8 +268,7 @@@ char *get_task_list(void
   */
  void sched_min_delay(struct sched *s)
  {
 -      s->select_timeout.tv_sec = 0;
 -      s->select_timeout.tv_usec = 1;
 +      s->select_timeout.tv_sec = s->select_timeout.tv_usec = 0;
  }
  
  /**
@@@ -311,17 -302,19 +311,19 @@@ void sched_request_timeout_ms(long unsi
   * \param barrier Absolute time before select() should return.
   * \param s Pointer to the scheduler struct.
   *
-  * If \a barrier is in the past, this function does nothing.
+  * \return If \a barrier is in the past, this function does nothing and returns
+  * zero. Otherwise it returns one.
   *
   * \sa sched_request_barrier_or_min_delay().
   */
void sched_request_barrier(struct timeval *barrier, struct sched *s)
int sched_request_barrier(struct timeval *barrier, struct sched *s)
  {
        struct timeval diff;
  
        if (tv_diff(now, barrier, &diff) > 0)
-               return;
+               return 0;
        sched_request_timeout(&diff, s);
+       return 1;
  }
  
  /**
   * \param barrier Absolute time before select() should return.
   * \param s Pointer to the scheduler struct.
   *
-  * If \a barrier is in the past, this function requests a minimal timeout.
+  * If \a barrier is in the past, this function requests a minimal timeout and
+  * returns zero. Otherwise it returns one.
   *
   * \sa sched_min_delay(), sched_request_barrier().
   */
void sched_request_barrier_or_min_delay(struct timeval *barrier, struct sched *s)
int sched_request_barrier_or_min_delay(struct timeval *barrier, struct sched *s)
  {
        struct timeval diff;
  
-       if (tv_diff(now, barrier, &diff) > 0)
-               return sched_min_delay(s);
+       if (tv_diff(now, barrier, &diff) > 0) {
+               sched_min_delay(s);
+               return 0;
+       }
        sched_request_timeout(&diff, s);
+       return 1;
  }