Diff for /libaitsched/src/hooks.c between versions 1.16 and 1.26

version 1.16, 2012/09/10 15:07:53 version 1.26, 2014/01/28 16:58:33
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012Copyright 2004 - 2014
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 62  sched_hook_init(void *root, void *arg __unused) Line 62  sched_hook_init(void *root, void *arg __unused)
         if (!r)          if (!r)
                 return (void*) -1;                  return (void*) -1;
   
   #ifndef KQ_DISABLE
         r->root_kq = kqueue();          r->root_kq = kqueue();
         if (r->root_kq == -1) {          if (r->root_kq == -1) {
                 LOGERR;                  LOGERR;
                 return (void*) -1;                  return (void*) -1;
         }          }
   #else
           r->root_kq ^= r->root_kq;
           FD_ZERO(&r->root_fds[0]);
           FD_ZERO(&r->root_fds[1]);
   #endif
   
         return NULL;          return NULL;
 }  }
Line 86  sched_hook_fini(void *root, void *arg __unused) Line 92  sched_hook_fini(void *root, void *arg __unused)
         if (!r)          if (!r)
                 return (void*) -1;                  return (void*) -1;
   
   #ifndef KQ_DISABLE
         if (r->root_kq > 2) {          if (r->root_kq > 2) {
                 close(r->root_kq);                  close(r->root_kq);
                 r->root_kq = 0;                  r->root_kq = 0;
         }          }
   #else
           FD_ZERO(&r->root_fds[1]);
           FD_ZERO(&r->root_fds[0]);
           r->root_kq ^= r->root_kq;
   #endif
   
         return NULL;          return NULL;
 }  }
Line 105  void * Line 117  void *
 sched_hook_cancel(void *task, void *arg __unused)  sched_hook_cancel(void *task, void *arg __unused)
 {  {
         sched_task_t *t = task;          sched_task_t *t = task;
   #ifndef KQ_DISABLE
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
   #else
           sched_root_task_t *r = NULL;
           register int i;
   #endif
 #ifdef AIO_SUPPORT  #ifdef AIO_SUPPORT
         struct aiocb *acb;          struct aiocb *acb;
 #ifdef EVFILT_LIO  #ifdef EVFILT_LIO
Line 117  sched_hook_cancel(void *task, void *arg __unused) Line 134  sched_hook_cancel(void *task, void *arg __unused)
   
         if (!t || !TASK_ROOT(t))          if (!t || !TASK_ROOT(t))
                 return (void*) -1;                  return (void*) -1;
   #ifdef KQ_DISABLE
           r = TASK_ROOT(t);
   #endif
   
         switch (TASK_TYPE(t)) {          switch (TASK_TYPE(t)) {
                 case taskREAD:                  case taskREAD:
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t));                          EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t));
 #else  #else
                         EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, (void*) TASK_FD(t));                          EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, (void*) TASK_FD(t));
 #endif  #endif
   #else
                           FD_CLR(TASK_FD(t), &r->root_fds[0]);
   
                           /* optimize select */
                           for (i = r->root_kq - 1; i > 2; i--)
                                   if (FD_ISSET(i, &r->root_fds[0]) || FD_ISSET(i, &r->root_fds[1]))
                                           break;
                           if (i > 2)
                                   r->root_kq = i + 1;
   #endif
                         break;                          break;
                 case taskWRITE:                  case taskWRITE:
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t));                          EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t));
 #else  #else
                         EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, (void*) TASK_FD(t));                          EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, (void*) TASK_FD(t));
 #endif  #endif
   #else
                           FD_CLR(TASK_FD(t), &r->root_fds[1]);
   
                           /* optimize select */
                           for (i = r->root_kq - 1; i > 2; i--)
                                   if (FD_ISSET(i, &r->root_fds[0]) || FD_ISSET(i, &r->root_fds[1]))
                                           break;
                           if (i > 2)
                                   r->root_kq = i + 1;
   #endif
                         break;                          break;
                 case taskALARM:                  case taskALARM:
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_DELETE,                           EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_DELETE, 
                                         0, 0, (intptr_t) TASK_DATA(t));                                          0, 0, (intptr_t) TASK_DATA(t));
Line 141  sched_hook_cancel(void *task, void *arg __unused) Line 184  sched_hook_cancel(void *task, void *arg __unused)
                         EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_DELETE,                           EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_DELETE, 
                                         0, 0, (void*) TASK_DATA(t));                                          0, 0, (void*) TASK_DATA(t));
 #endif  #endif
   #endif
                         break;                          break;
                 case taskNODE:                  case taskNODE:
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t));                          EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t));
 #else  #else
                         EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, EV_DELETE, 0, 0, (void*) TASK_FD(t));                          EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, EV_DELETE, 0, 0, (void*) TASK_FD(t));
 #endif  #endif
   #endif
                         break;                          break;
                 case taskPROC:                  case taskPROC:
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));                          EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));
 #else  #else
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, EV_DELETE, 0, 0, (void*) TASK_VAL(t));                          EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, EV_DELETE, 0, 0, (void*) TASK_VAL(t));
 #endif  #endif
   #endif
                         break;                          break;
                 case taskSIGNAL:                  case taskSIGNAL:
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));                          EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));
 #else  #else
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_DELETE, 0, 0, (void*) TASK_VAL(t));                          EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_DELETE, 0, 0, (void*) TASK_VAL(t));
 #endif  #endif
                           /* restore signal */
                           signal(TASK_VAL(t), SIG_DFL);
   #endif
                         break;                          break;
 #ifdef AIO_SUPPORT  #ifdef AIO_SUPPORT
                 case taskAIO:                  case taskAIO:
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_AIO, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));                          EV_SET(&chg[0], TASK_VAL(t), EVFILT_AIO, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));
 #else  #else
Line 177  sched_hook_cancel(void *task, void *arg __unused) Line 230  sched_hook_cancel(void *task, void *arg __unused)
                                 free(acb);                                  free(acb);
                                 TASK_VAL(t) = 0;                                  TASK_VAL(t) = 0;
                         }                          }
   #endif
                         break;                          break;
 #ifdef EVFILT_LIO  #ifdef EVFILT_LIO
                 case taskLIO:                  case taskLIO:
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_LIO, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));                          EV_SET(&chg[0], TASK_VAL(t), EVFILT_LIO, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));
 #else  #else
Line 195  sched_hook_cancel(void *task, void *arg __unused) Line 250  sched_hook_cancel(void *task, void *arg __unused)
                                 free(acbs);                                  free(acbs);
                                 TASK_VAL(t) = 0;                                  TASK_VAL(t) = 0;
                         }                          }
   #endif
                         break;                          break;
 #endif  /* EVFILT_LIO */  #endif  /* EVFILT_LIO */
 #endif  /* AIO_SUPPORT */  #endif  /* AIO_SUPPORT */
 #ifdef EVFILT_USER  #ifdef EVFILT_USER
                 case taskUSER:                  case taskUSER:
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));                          EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));
 #else  #else
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, EV_DELETE, 0, 0, (void*) TASK_VAL(t));                          EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, EV_DELETE, 0, 0, (void*) TASK_VAL(t));
 #endif  #endif
                         break;  
 #endif  #endif
                           break;
   #endif  /* EVFILT_USER */
                 case taskTHREAD:                  case taskTHREAD:
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
                         pthread_cancel((pthread_t) TASK_VAL(t));                          pthread_cancel((pthread_t) TASK_VAL(t));
 #endif  #endif
                           return NULL;
   #if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME)
                   case taskRTC:
                           timer_delete((timer_t) TASK_FLAG(t));
                           schedCancel((sched_task_t*) TASK_RET(t));
                           return NULL;
   #endif  /* HAVE_TIMER_CREATE */
                 default:                  default:
                         return NULL;                          return NULL;
         }          }
   
   #ifndef KQ_DISABLE
         kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout);          kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout);
   #endif
         return NULL;          return NULL;
 }  }
   
Line 266  void * Line 333  void *
 sched_hook_read(void *task, void *arg __unused)  sched_hook_read(void *task, void *arg __unused)
 {  {
         sched_task_t *t = task;          sched_task_t *t = task;
   #ifndef KQ_DISABLE
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
   #else
           sched_root_task_t *r = NULL;
   #endif
   
         if (!t || !TASK_ROOT(t))          if (!t || !TASK_ROOT(t))
                 return (void*) -1;                  return (void*) -1;
   #ifdef KQ_DISABLE
           r = TASK_ROOT(t);
   #endif
   
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
         EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_FD(t));          EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_FD(t));
 #else  #else
Line 284  sched_hook_read(void *task, void *arg __unused) Line 359  sched_hook_read(void *task, void *arg __unused)
                         LOGERR;                          LOGERR;
                 return (void*) -1;                  return (void*) -1;
         }          }
   #else
           FD_SET(TASK_FD(t), &r->root_fds[0]);
           if (TASK_FD(t) >= r->root_kq)
                   r->root_kq = TASK_FD(t) + 1;
   #endif
   
         return NULL;          return NULL;
 }  }
Line 299  void * Line 379  void *
 sched_hook_write(void *task, void *arg __unused)  sched_hook_write(void *task, void *arg __unused)
 {  {
         sched_task_t *t = task;          sched_task_t *t = task;
   #ifndef KQ_DISABLE
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
   #else
           sched_root_task_t *r = NULL;
   #endif
   
         if (!t || !TASK_ROOT(t))          if (!t || !TASK_ROOT(t))
                 return (void*) -1;                  return (void*) -1;
   #ifdef KQ_DISABLE
           r = TASK_ROOT(t);
   #endif
   
   #ifndef KQ_DISABLE
 #ifdef __NetBSD__  #ifdef __NetBSD__
         EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_FD(t));          EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_FD(t));
 #else  #else
Line 317  sched_hook_write(void *task, void *arg __unused) Line 405  sched_hook_write(void *task, void *arg __unused)
                         LOGERR;                          LOGERR;
                 return (void*) -1;                  return (void*) -1;
         }          }
   #else
           FD_SET(TASK_FD(t), &r->root_fds[1]);
           if (TASK_FD(t) >= r->root_kq)
                   r->root_kq = TASK_FD(t) + 1;
   #endif
   
         return NULL;          return NULL;
 }  }
Line 331  sched_hook_write(void *task, void *arg __unused) Line 424  sched_hook_write(void *task, void *arg __unused)
 void *  void *
 sched_hook_alarm(void *task, void *arg __unused)  sched_hook_alarm(void *task, void *arg __unused)
 {  {
   #ifndef KQ_DISABLE
         sched_task_t *t = task;          sched_task_t *t = task;
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
Line 339  sched_hook_alarm(void *task, void *arg __unused) Line 433  sched_hook_alarm(void *task, void *arg __unused)
                 return (void*) -1;                  return (void*) -1;
   
 #ifdef __NetBSD__  #ifdef __NetBSD__
        EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0,         EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_ADD | EV_CLEAR, 0, 
                         t->task_val.ts.tv_sec * 1000 + t->task_val.ts.tv_nsec / 1000000,                           t->task_val.ts.tv_sec * 1000 + t->task_val.ts.tv_nsec / 1000000, 
                         (intptr_t) TASK_DATA(t));                          (intptr_t) TASK_DATA(t));
 #else  #else
        EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0,         EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_ADD | EV_CLEAR, 0, 
                         t->task_val.ts.tv_sec * 1000 + t->task_val.ts.tv_nsec / 1000000,                           t->task_val.ts.tv_sec * 1000 + t->task_val.ts.tv_nsec / 1000000, 
                         (void*) TASK_DATA(t));                          (void*) TASK_DATA(t));
 #endif  #endif
Line 355  sched_hook_alarm(void *task, void *arg __unused) Line 449  sched_hook_alarm(void *task, void *arg __unused)
                 return (void*) -1;                  return (void*) -1;
         }          }
   
   #endif
         return NULL;          return NULL;
 }  }
   
Line 368  sched_hook_alarm(void *task, void *arg __unused) Line 463  sched_hook_alarm(void *task, void *arg __unused)
 void *  void *
 sched_hook_node(void *task, void *arg __unused)  sched_hook_node(void *task, void *arg __unused)
 {  {
   #ifndef KQ_DISABLE
         sched_task_t *t = task;          sched_task_t *t = task;
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
Line 392  sched_hook_node(void *task, void *arg __unused) Line 488  sched_hook_node(void *task, void *arg __unused)
                 return (void*) -1;                  return (void*) -1;
         }          }
   
   #endif
         return NULL;          return NULL;
 }  }
   
Line 405  sched_hook_node(void *task, void *arg __unused) Line 502  sched_hook_node(void *task, void *arg __unused)
 void *  void *
 sched_hook_proc(void *task, void *arg __unused)  sched_hook_proc(void *task, void *arg __unused)
 {  {
   #ifndef KQ_DISABLE
         sched_task_t *t = task;          sched_task_t *t = task;
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
Line 427  sched_hook_proc(void *task, void *arg __unused) Line 525  sched_hook_proc(void *task, void *arg __unused)
                 return (void*) -1;                  return (void*) -1;
         }          }
   
   #endif
         return NULL;          return NULL;
 }  }
   
Line 440  sched_hook_proc(void *task, void *arg __unused) Line 539  sched_hook_proc(void *task, void *arg __unused)
 void *  void *
 sched_hook_signal(void *task, void *arg __unused)  sched_hook_signal(void *task, void *arg __unused)
 {  {
   #ifndef KQ_DISABLE
         sched_task_t *t = task;          sched_task_t *t = task;
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
Line 447  sched_hook_signal(void *task, void *arg __unused) Line 547  sched_hook_signal(void *task, void *arg __unused)
         if (!t || !TASK_ROOT(t))          if (!t || !TASK_ROOT(t))
                 return (void*) -1;                  return (void*) -1;
   
           /* ignore signal */
           signal(TASK_VAL(t), SIG_IGN);
   
 #ifdef __NetBSD__  #ifdef __NetBSD__
        EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_ADD, 0, 0, (intptr_t) TASK_VAL(t));        EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_VAL(t));
 #else  #else
        EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_ADD, 0, 0, (void*) TASK_VAL(t));        EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_ADD | EV_CLEAR, 0, 0, (void*) TASK_VAL(t));
 #endif  #endif
         if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {          if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {
                 if (TASK_ROOT(t)->root_hooks.hook_exec.exception)                  if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
Line 459  sched_hook_signal(void *task, void *arg __unused) Line 562  sched_hook_signal(void *task, void *arg __unused)
                         LOGERR;                          LOGERR;
                 return (void*) -1;                  return (void*) -1;
         }          }
   #else
   #if 0
           sched_task_t *t = task;
           struct sigaction sa;
   
           memset(&sa, 0, sizeof sa);
           sigemptyset(&sa.sa_mask);
           sa.sa_handler = _sched_sigHandler;
           sa.sa_flags = SA_RESETHAND | SA_RESTART;
   
           if (sigaction(TASK_VAL(t), &sa, NULL) == -1) {
                   if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
                           TASK_ROOT(t)->root_hooks.hook_exec.exception(TASK_ROOT(t), NULL);
                   else
                           LOGERR;
                   return (void*) -1;
           }
   #endif  /* 0 */
   #endif
         return NULL;          return NULL;
 }  }
   
Line 474  sched_hook_signal(void *task, void *arg __unused) Line 595  sched_hook_signal(void *task, void *arg __unused)
 void *  void *
 sched_hook_user(void *task, void *arg __unused)  sched_hook_user(void *task, void *arg __unused)
 {  {
   #ifndef KQ_DISABLE
         sched_task_t *t = task;          sched_task_t *t = task;
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
Line 496  sched_hook_user(void *task, void *arg __unused) Line 618  sched_hook_user(void *task, void *arg __unused)
                 return (void*) -1;                  return (void*) -1;
         }          }
   
   #endif
         return NULL;          return NULL;
 }  }
 #endif  #endif
Line 513  sched_hook_fetch(void *root, void *arg __unused) Line 636  sched_hook_fetch(void *root, void *arg __unused)
         sched_root_task_t *r = root;          sched_root_task_t *r = root;
         sched_task_t *task, *tmp;          sched_task_t *task, *tmp;
         struct timespec now, m, mtmp;          struct timespec now, m, mtmp;
        struct timespec *timeout;#ifndef KQ_DISABLE
         struct kevent evt[1], res[KQ_EVENTS];          struct kevent evt[1], res[KQ_EVENTS];
           struct timespec *timeout;
   #else
           struct timeval *timeout, tv;
           fd_set rfd, wfd, xfd;
   #endif
         register int i, flg;          register int i, flg;
         int en;          int en;
 #ifdef AIO_SUPPORT  #ifdef AIO_SUPPORT
Line 589  sched_hook_fetch(void *root, void *arg __unused) Line 717  sched_hook_fetch(void *root, void *arg __unused)
                 /* set wait INFTIM */                  /* set wait INFTIM */
                 sched_timespecinf(&r->root_wait);                  sched_timespecinf(&r->root_wait);
         }          }
#else#else   /* ! TIMER_WITHOUT_SORT */
         if (!TAILQ_FIRST(&r->root_task) && (task = TAILQ_FIRST(&r->root_timer))) {          if (!TAILQ_FIRST(&r->root_task) && (task = TAILQ_FIRST(&r->root_timer))) {
                 clock_gettime(CLOCK_MONOTONIC, &now);                  clock_gettime(CLOCK_MONOTONIC, &now);
   
Line 600  sched_hook_fetch(void *root, void *arg __unused) Line 728  sched_hook_fetch(void *root, void *arg __unused)
                 /* set wait INFTIM */                  /* set wait INFTIM */
                 sched_timespecinf(&r->root_wait);                  sched_timespecinf(&r->root_wait);
         }          }
#endif#endif  /* TIMER_WITHOUT_SORT */
         /* if present member of task, set NOWAIT */          /* if present member of task, set NOWAIT */
         if (TAILQ_FIRST(&r->root_task))          if (TAILQ_FIRST(&r->root_task))
                 sched_timespecclear(&r->root_wait);                  sched_timespecclear(&r->root_wait);
   
        if (r->root_wait.tv_sec != -1 && r->root_wait.tv_nsec != -1)        if (r->root_wait.tv_sec != -1 && r->root_wait.tv_nsec != -1) {
 #ifndef KQ_DISABLE
                 timeout = &r->root_wait;                  timeout = &r->root_wait;
        else if (sched_timespecisinf(&r->root_poll))#else
                 sched_timespec2val(&r->root_wait, &tv);
                 timeout = &tv;
 #endif  /* KQ_DISABLE */
         } else if (sched_timespecisinf(&r->root_poll))
                 timeout = NULL;                  timeout = NULL;
        else        else {
 #ifndef KQ_DISABLE
                 timeout = &r->root_poll;                  timeout = &r->root_poll;
   #else
                   sched_timespec2val(&r->root_poll, &tv);
                   timeout = &tv;
   #endif  /* KQ_DISABLE */
           }
   
   #ifndef KQ_DISABLE
         if ((en = kevent(r->root_kq, NULL, 0, res, KQ_EVENTS, timeout)) == -1) {          if ((en = kevent(r->root_kq, NULL, 0, res, KQ_EVENTS, timeout)) == -1) {
   #else
           rfd = xfd = r->root_fds[0];
           wfd = r->root_fds[1];
           if ((en = select(r->root_kq, &rfd, &wfd, &xfd, timeout)) == -1) {
   #endif  /* KQ_DISABLE */
                 if (r->root_hooks.hook_exec.exception) {                  if (r->root_hooks.hook_exec.exception) {
                         if (r->root_hooks.hook_exec.exception(r, NULL))                          if (r->root_hooks.hook_exec.exception(r, NULL))
                                 return NULL;                                  return NULL;
                 } else if (errno != EINTR)                  } else if (errno != EINTR)
                         LOGERR;                          LOGERR;
                return NULL;                goto skip_event;
         }          }
   
           /* kevent dispatcher */
         now.tv_sec = now.tv_nsec = 0;          now.tv_sec = now.tv_nsec = 0;
         /* Go and catch the cat into pipes ... */          /* Go and catch the cat into pipes ... */
   #ifndef KQ_DISABLE
         for (i = 0; i < en; i++) {          for (i = 0; i < en; i++) {
                 memcpy(evt, &res[i], sizeof evt);                  memcpy(evt, &res[i], sizeof evt);
                 evt->flags = EV_DELETE;                  evt->flags = EV_DELETE;
Line 635  sched_hook_fetch(void *root, void *arg __unused) Line 783  sched_hook_fetch(void *root, void *arg __unused)
                                         else {                                          else {
                                                 flg++;                                                  flg++;
                                                 TASK_RET(task) = res[i].data;                                                  TASK_RET(task) = res[i].data;
                                                TASK_FLAG(task) = res[i].fflags;                                                TASK_FLAG(task) = (u_long) res[i].fflags;
                                         }                                          }
                                         /* remove read handle */                                          /* remove read handle */
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
Line 688  sched_hook_fetch(void *root, void *arg __unused) Line 836  sched_hook_fetch(void *root, void *arg __unused)
                                         else {                                          else {
                                                 flg++;                                                  flg++;
                                                 TASK_RET(task) = res[i].data;                                                  TASK_RET(task) = res[i].data;
                                                TASK_FLAG(task) = res[i].fflags;                                                TASK_FLAG(task) = (u_long) res[i].fflags;
                                         }                                          }
                                         /* remove write handle */                                          /* remove write handle */
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
Line 741  sched_hook_fetch(void *root, void *arg __unused) Line 889  sched_hook_fetch(void *root, void *arg __unused)
                                         else {                                          else {
                                                 flg++;                                                  flg++;
                                                 TASK_RET(task) = res[i].data;                                                  TASK_RET(task) = res[i].data;
                                                TASK_FLAG(task) = res[i].fflags;                                                TASK_FLAG(task) = (u_long) res[i].fflags;
                                         }                                          }
                                         /* remove alarm handle */                                          /* remove alarm handle */
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
Line 772  sched_hook_fetch(void *root, void *arg __unused) Line 920  sched_hook_fetch(void *root, void *arg __unused)
                                         else {                                          else {
                                                 flg++;                                                  flg++;
                                                 TASK_RET(task) = res[i].data;                                                  TASK_RET(task) = res[i].data;
                                                TASK_FLAG(task) = res[i].fflags;                                                TASK_FLAG(task) = (u_long) res[i].fflags;
                                         }                                          }
                                         /* remove node handle */                                          /* remove node handle */
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
Line 803  sched_hook_fetch(void *root, void *arg __unused) Line 951  sched_hook_fetch(void *root, void *arg __unused)
                                         else {                                          else {
                                                 flg++;                                                  flg++;
                                                 TASK_RET(task) = res[i].data;                                                  TASK_RET(task) = res[i].data;
                                                TASK_FLAG(task) = res[i].fflags;                                                TASK_FLAG(task) = (u_long) res[i].fflags;
                                         }                                          }
                                         /* remove proc handle */                                          /* remove proc handle */
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
Line 834  sched_hook_fetch(void *root, void *arg __unused) Line 982  sched_hook_fetch(void *root, void *arg __unused)
                                         else {                                          else {
                                                 flg++;                                                  flg++;
                                                 TASK_RET(task) = res[i].data;                                                  TASK_RET(task) = res[i].data;
                                                TASK_FLAG(task) = res[i].fflags;                                                TASK_FLAG(task) = (u_long) res[i].fflags;
                                         }                                          }
                                         /* remove signal handle */                                          /* remove signal handle */
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
Line 867  sched_hook_fetch(void *root, void *arg __unused) Line 1015  sched_hook_fetch(void *root, void *arg __unused)
                                         else {                                          else {
                                                 flg++;                                                  flg++;
                                                 TASK_RET(task) = res[i].data;                                                  TASK_RET(task) = res[i].data;
                                                TASK_FLAG(task) = res[i].fflags;                                                TASK_FLAG(task) = (u_long) res[i].fflags;
                                         }                                          }
                                         /* remove user handle */                                          /* remove user handle */
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
Line 909  sched_hook_fetch(void *root, void *arg __unused) Line 1057  sched_hook_fetch(void *root, void *arg __unused)
                                         else {                                          else {
                                                 flg++;                                                  flg++;
                                                 TASK_RET(task) = res[i].data;                                                  TASK_RET(task) = res[i].data;
                                                TASK_FLAG(task) = res[i].fflags;                                                TASK_FLAG(task) = (u_long) res[i].fflags;
                                         }                                          }
                                         /* remove user handle */                                          /* remove user handle */
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
Line 959  sched_hook_fetch(void *root, void *arg __unused) Line 1107  sched_hook_fetch(void *root, void *arg __unused)
                                         else {                                          else {
                                                 flg++;                                                  flg++;
                                                 TASK_RET(task) = res[i].data;                                                  TASK_RET(task) = res[i].data;
                                                TASK_FLAG(task) = res[i].fflags;                                                TASK_FLAG(task) = (u_long) res[i].fflags;
                                         }                                          }
                                         /* remove user handle */                                          /* remove user handle */
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
Line 992  sched_hook_fetch(void *root, void *arg __unused) Line 1140  sched_hook_fetch(void *root, void *arg __unused)
                                 LOGERR;                                  LOGERR;
                 }                  }
         }          }
   #else   /* end of kevent dispatcher */
           for (i = 0; i < r->root_kq; i++) {
                   if (FD_ISSET(i, &rfd) || FD_ISSET(i, &xfd)) {
                           flg = 0;
                           TAILQ_FOREACH_SAFE(task, &r->root_read, task_node, tmp) {
                                   if (TASK_FD(task) != i)
                                           continue;
                                   else {
                                           flg++;
                                           TASK_FLAG(task) = ioctl(TASK_FD(task), 
                                                           FIONREAD, &TASK_RET(task));
                                   }
                                   /* remove read handle */
   #ifdef HAVE_LIBPTHREAD
                                   pthread_mutex_lock(&r->root_mtx[taskREAD]);
   #endif
                                   TAILQ_REMOVE(&r->root_read, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                   pthread_mutex_unlock(&r->root_mtx[taskREAD]);
   #endif
                                   if (r->root_hooks.hook_exec.exception) {
                                           if (r->root_hooks.hook_exec.exception(r, NULL)) {
                                                   task->task_type = taskUNUSE;
   #ifdef HAVE_LIBPTHREAD
                                                   pthread_mutex_lock(&r->root_mtx[taskUNUSE]);
   #endif
                                                   TAILQ_INSERT_TAIL(&r->root_unuse, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                                   pthread_mutex_unlock(&r->root_mtx[taskUNUSE]);
   #endif
                                           } else {
                                                   task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                                                   pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                                                   TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                                   pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                                           }
                                   } else {
                                           task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                                           TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                                   }
                           }
                           /* if match equal to 1, remove resouce */
                           if (flg == 1)
                                   FD_CLR(i, &r->root_fds[0]);
                   }
   
                   if (FD_ISSET(i, &wfd)) {
                           flg = 0;
                           TAILQ_FOREACH_SAFE(task, &r->root_write, task_node, tmp) {
                                   if (TASK_FD(task) != i)
                                           continue;
                                   else {
                                           flg++;
                                           TASK_FLAG(task) = ioctl(TASK_FD(task), 
                                                           FIONWRITE, &TASK_RET(task));
                                   }
                                   /* remove write handle */
   #ifdef HAVE_LIBPTHREAD
                                   pthread_mutex_lock(&r->root_mtx[taskWRITE]);
   #endif
                                   TAILQ_REMOVE(&r->root_write, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                   pthread_mutex_unlock(&r->root_mtx[taskWRITE]);
   #endif
                                   if (r->root_hooks.hook_exec.exception) {
                                           if (r->root_hooks.hook_exec.exception(r, NULL)) {
                                                   task->task_type = taskUNUSE;
   #ifdef HAVE_LIBPTHREAD
                                                   pthread_mutex_lock(&r->root_mtx[taskUNUSE]);
   #endif
                                                   TAILQ_INSERT_TAIL(&r->root_unuse, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                                   pthread_mutex_unlock(&r->root_mtx[taskUNUSE]);
   #endif
                                           } else {
                                                   task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                                                   pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                                                   TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                                   pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                                           }
                                   } else {
                                           task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                                           TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                                   }
                           }
                           /* if match equal to 1, remove resouce */
                           if (flg == 1)
                                   FD_CLR(i, &r->root_fds[1]);
                   }
           }
   
           /* optimize select */
           for (i = r->root_kq - 1; i > 2; i--)
                   if (FD_ISSET(i, &r->root_fds[0]) || FD_ISSET(i, &r->root_fds[1]))
                           break;
           if (i > 2)
                   r->root_kq = i + 1;
   #endif  /* KQ_DISABLE */
   
   skip_event:
         /* timer update & put in ready queue */          /* timer update & put in ready queue */
         clock_gettime(CLOCK_MONOTONIC, &now);          clock_gettime(CLOCK_MONOTONIC, &now);
   
Line 1112  sched_hook_condition(void *root, void *arg) Line 1379  sched_hook_condition(void *root, void *arg)
   
         return (void*) (r->root_cond - *(intptr_t*) arg);          return (void*) (r->root_cond - *(intptr_t*) arg);
 }  }
   
   /*
    * sched_hook_rtc() - Default RTC hook
    *
    * @task = current task
    * @arg = unused
    * return: <0 errors and 0 ok
    */
   #if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME)
   void *
   sched_hook_rtc(void *task, void *arg __unused)
   {
           sched_task_t *sigt = NULL, *t = task;
           struct itimerspec its;
           struct sigevent evt;
           timer_t tmr;
   
           if (!t || !TASK_ROOT(t))
                   return (void*) -1;
   
           memset(&evt, 0, sizeof evt);
           evt.sigev_notify = SIGEV_SIGNAL;
           evt.sigev_signo = (intptr_t) TASK_DATA(t) + SIGRTMIN;
           evt.sigev_value.sival_ptr = TASK_DATA(t);
   
           if (timer_create(CLOCK_MONOTONIC, &evt, &tmr) == -1) {
                   if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
                           TASK_ROOT(t)->root_hooks.hook_exec.exception(TASK_ROOT(t), NULL);
                   else
                           LOGERR;
                   return (void*) -1;
           } else
                   TASK_FLAG(t) = (u_long) tmr;
   
           if (!(sigt = schedSignal(TASK_ROOT(t), _sched_rtcWrapper, TASK_ARG(t), evt.sigev_signo, 
                                   t, (size_t) tmr))) {
                   if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
                           TASK_ROOT(t)->root_hooks.hook_exec.exception(TASK_ROOT(t), NULL);
                   else
                           LOGERR;
                   timer_delete(tmr);
                   return (void*) -1;
           } else
                   TASK_RET(t) = (uintptr_t) sigt;
   
           memset(&its, 0, sizeof its);
           its.it_value.tv_sec = t->task_val.ts.tv_sec;
           its.it_value.tv_nsec = t->task_val.ts.tv_nsec;
   
           if (timer_settime(tmr, TIMER_RELTIME, &its, NULL) == -1) {
                   if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
                           TASK_ROOT(t)->root_hooks.hook_exec.exception(TASK_ROOT(t), NULL);
                   else
                           LOGERR;
                   schedCancel(sigt);
                   timer_delete(tmr);
                   return (void*) -1;
           }
   
           return NULL;
   }
   #endif  /* HAVE_TIMER_CREATE */

Removed from v.1.16  
changed lines
  Added in v.1.26


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>