Diff for /libaitsched/src/tasks.c between versions 1.1.1.1 and 1.4.2.1

version 1.1.1.1, 2011/08/05 15:52:00 version 1.4.2.1, 2012/01/08 03:50:11
Line 46  SUCH DAMAGE. Line 46  SUCH DAMAGE.
 #include "global.h"  #include "global.h"
   
   
   #pragma GCC visibility push(hidden)
   
   inline sched_task_t *
   _sched_useTask(sched_root_task_t * __restrict root)
   {
           sched_task_t *task;
   
           TAILQ_FOREACH(task, &root->root_unuse, task_node) {
                   if (!TASK_ISLOCKED(task)) {
   #ifdef HAVE_LIBPTHREAD
                           pthread_mutex_lock(&root->root_mtx[taskUNUSE]);
   #endif
                           TAILQ_REMOVE(&root->root_unuse, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                           pthread_mutex_unlock(&root->root_mtx[taskUNUSE]);
   #endif
                           break;
                   }
           }
   
           if (!task) {
                   task = malloc(sizeof(sched_task_t));
                   if (!task) {
                           LOGERR;
                           return NULL;
                   }
           }
   
           return task;
   }
   
   inline sched_task_t *
   _sched_unuseTask(sched_task_t * __restrict task)
   {
           TASK_UNLOCK(task);
           TASK_TYPE(task) = taskUNUSE;
   #ifdef HAVE_LIBPTHREAD
           pthread_mutex_lock(&TASK_ROOT(task)->root_mtx[taskUNUSE]);
   #endif
           TAILQ_INSERT_TAIL(&TASK_ROOT(task)->root_unuse, task, task_node);
   #ifdef HAVE_LIBPTHREAD
           pthread_mutex_unlock(&TASK_ROOT(task)->root_mtx[taskUNUSE]);
   #endif
           task = NULL;
   
           return task;
   }
   
   #pragma GCC visibility pop
   
   
 /*  /*
 * schedRead() - Add READ task to scheduler queue * schedRead() - Add READ I/O task to scheduler queue
  * @root = root task   * @root = root task
  * @func = task execution function   * @func = task execution function
  * @arg = 1st func argument   * @arg = 1st func argument
 * @... = next func arguments, like fd handle * @fd = fd handle
  * return: NULL error or !=NULL new queued task   * return: NULL error or !=NULL new queued task
  */   */
 sched_task_t *  sched_task_t *
schedRead(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, ...)schedRead(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, int fd)
 {  {
         sched_task_t *task;          sched_task_t *task;
         void *ptr;          void *ptr;
         va_list lst;  
   
         if (!root || !func)          if (!root || !func)
                 return NULL;                  return NULL;
   
         /* get new task */          /* get new task */
        if ((task = TAILQ_FIRST(&root->root_unuse)))        if (!(task = _sched_useTask(root)))
                TAILQ_REMOVE(&root->root_unuse, task, task_node);                return NULL;
        else { 
                task = malloc(sizeof(sched_task_t)); 
                if (!task) { 
                        LOGERR; 
                        return NULL; 
                } 
        } 
   
         memset(task, 0, sizeof(sched_task_t));          memset(task, 0, sizeof(sched_task_t));
         task->task_id = 0;          task->task_id = 0;
        task->task_type = taskREAD;        task->task_lock = 0;
        task->task_root = root; 
         task->task_func = func;          task->task_func = func;
           TASK_TYPE(task) = taskREAD;
           TASK_ROOT(task) = root;
   
         TASK_ARG(task) = arg;          TASK_ARG(task) = arg;
        va_start(lst, arg);        TASK_FD(task) = fd;
        TASK_FD(task) = va_arg(lst, int); 
        va_end(lst); 
   
         if (root->root_hooks.hook_add.read)          if (root->root_hooks.hook_add.read)
                 ptr = root->root_hooks.hook_add.read(task, NULL);                  ptr = root->root_hooks.hook_add.read(task, NULL);
         else          else
                 ptr = NULL;                  ptr = NULL;
   
        if (!ptr)        if (!ptr) {
 #ifdef HAVE_LIBPTHREAD
                 pthread_mutex_lock(&root->root_mtx[taskREAD]);
 #endif
                 TAILQ_INSERT_TAIL(&root->root_read, task, task_node);                  TAILQ_INSERT_TAIL(&root->root_read, task, task_node);
        else {#ifdef HAVE_LIBPTHREAD
                task->task_type = taskUNUSE;                pthread_mutex_unlock(&root->root_mtx[taskREAD]);
                TAILQ_INSERT_TAIL(&root->root_unuse, task, task_node);#endif
                task = NULL;        } else
        }                task = _sched_unuseTask(task);
   
         return task;          return task;
 }  }
   
 /*  /*
 * schedWrite() - Add WRITE task to scheduler queue * schedWrite() - Add WRITE I/O task to scheduler queue
  * @root = root task   * @root = root task
  * @func = task execution function   * @func = task execution function
  * @arg = 1st func argument   * @arg = 1st func argument
 * @... = next func arguments, like fd handle * @fd = fd handle
  * return: NULL error or !=NULL new queued task   * return: NULL error or !=NULL new queued task
  */   */
 sched_task_t *  sched_task_t *
schedWrite(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, ...)schedWrite(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, int fd)
 {  {
         sched_task_t *task;          sched_task_t *task;
         void *ptr;          void *ptr;
         va_list lst;  
   
         if (!root || !func)          if (!root || !func)
                 return NULL;                  return NULL;
   
         /* get new task */          /* get new task */
        if ((task = TAILQ_FIRST(&root->root_unuse)))        if (!(task = _sched_useTask(root)))
                TAILQ_REMOVE(&root->root_unuse, task, task_node);                return NULL;
        else { 
                task = malloc(sizeof(sched_task_t)); 
                if (!task) { 
                        LOGERR; 
                        return NULL; 
                } 
        } 
   
         memset(task, 0, sizeof(sched_task_t));          memset(task, 0, sizeof(sched_task_t));
         task->task_id = 0;          task->task_id = 0;
        task->task_type = taskWRITE;        task->task_lock = 0;
        task->task_root = root; 
         task->task_func = func;          task->task_func = func;
           TASK_TYPE(task) = taskWRITE;
           TASK_ROOT(task) = root;
   
         TASK_ARG(task) = arg;          TASK_ARG(task) = arg;
        va_start(lst, arg);        TASK_FD(task) = fd;
        TASK_FD(task) = va_arg(lst, int); 
        va_end(lst); 
   
         if (root->root_hooks.hook_add.write)          if (root->root_hooks.hook_add.write)
                 ptr = root->root_hooks.hook_add.write(task, NULL);                  ptr = root->root_hooks.hook_add.write(task, NULL);
         else          else
                 ptr = NULL;                  ptr = NULL;
   
        if (!ptr)        if (!ptr) {
 #ifdef HAVE_LIBPTHREAD
                 pthread_mutex_lock(&root->root_mtx[taskWRITE]);
 #endif
                 TAILQ_INSERT_TAIL(&root->root_write, task, task_node);                  TAILQ_INSERT_TAIL(&root->root_write, task, task_node);
        else {#ifdef HAVE_LIBPTHREAD
                task->task_type = taskUNUSE;                pthread_mutex_unlock(&root->root_mtx[taskWRITE]);
                TAILQ_INSERT_TAIL(&root->root_unuse, task, task_node);#endif
                task = NULL;        } else
        }                task = _sched_unuseTask(task);
   
         return task;          return task;
 }  }
Line 163  schedWrite(sched_root_task_t * __restrict root, sched_ Line 202  schedWrite(sched_root_task_t * __restrict root, sched_
  * @root = root task   * @root = root task
  * @func = task execution function   * @func = task execution function
  * @arg = 1st func argument   * @arg = 1st func argument
 * @... = next func arguments in microSecs, define period 1sec == 1000000 * @tv = timeout argument structure
  * return: NULL error or !=NULL new queued task   * return: NULL error or !=NULL new queued task
  */   */
 sched_task_t *  sched_task_t *
schedTimer(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, ...)schedTimer(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, struct timeval tv)
 {  {
         sched_task_t *task, *t = NULL;          sched_task_t *task, *t = NULL;
         void *ptr;          void *ptr;
         va_list lst;  
         struct timeval now;          struct timeval now;
         struct timespec nw;          struct timespec nw;
         u_int tim;  
   
         if (!root || !func)          if (!root || !func)
                 return NULL;                  return NULL;
   
         /* get new task */          /* get new task */
        if ((task = TAILQ_FIRST(&root->root_unuse)))        if (!(task = _sched_useTask(root)))
                TAILQ_REMOVE(&root->root_unuse, task, task_node);                return NULL;
        else { 
                task = malloc(sizeof(sched_task_t)); 
                if (!task) { 
                        LOGERR; 
                        return NULL; 
                } 
        } 
   
         memset(task, 0, sizeof(sched_task_t));          memset(task, 0, sizeof(sched_task_t));
         task->task_id = 0;          task->task_id = 0;
        task->task_type = taskTIMER;        task->task_lock = 0;
        task->task_root = root; 
         task->task_func = func;          task->task_func = func;
           TASK_TYPE(task) = taskTIMER;
           TASK_ROOT(task) = root;
   
         TASK_ARG(task) = arg;          TASK_ARG(task) = arg;
         va_start(lst, arg);  
         tim = va_arg(lst, u_int);  
         va_end(lst);  
   
         /* calculate timeval structure */          /* calculate timeval structure */
         clock_gettime(CLOCK_MONOTONIC, &nw);          clock_gettime(CLOCK_MONOTONIC, &nw);
        now.tv_sec = nw.tv_sec + tim / 1000000;        now.tv_sec = nw.tv_sec + tv.tv_sec;
        now.tv_usec = nw.tv_nsec / 1000 + (tim % 1000000);        now.tv_usec = nw.tv_nsec / 1000 + tv.tv_usec;
         if (now.tv_usec >= 1000000) {          if (now.tv_usec >= 1000000) {
                 now.tv_sec++;                  now.tv_sec++;
                 now.tv_usec -= 1000000;                  now.tv_usec -= 1000000;
Line 220  schedTimer(sched_root_task_t * __restrict root, sched_ Line 248  schedTimer(sched_root_task_t * __restrict root, sched_
                 ptr = NULL;                  ptr = NULL;
   
         if (!ptr) {          if (!ptr) {
   #ifdef HAVE_LIBPTHREAD
                   pthread_mutex_lock(&root->root_mtx[taskTIMER]);
   #endif
 #ifdef TIMER_WITHOUT_SORT  #ifdef TIMER_WITHOUT_SORT
                 TAILQ_INSERT_TAIL(&root->root_timer, task, task_node);                  TAILQ_INSERT_TAIL(&root->root_timer, task, task_node);
 #else  #else
Line 231  schedTimer(sched_root_task_t * __restrict root, sched_ Line 262  schedTimer(sched_root_task_t * __restrict root, sched_
                 else                  else
                         TAILQ_INSERT_BEFORE(t, task, task_node);                          TAILQ_INSERT_BEFORE(t, task, task_node);
 #endif  #endif
        } else {#ifdef HAVE_LIBPTHREAD
                task->task_type = taskUNUSE;                pthread_mutex_unlock(&root->root_mtx[taskTIMER]);
                TAILQ_INSERT_TAIL(&root->root_unuse, task, task_node);#endif
                task = NULL;        } else
        }                task = _sched_unuseTask(task);
   
         return task;          return task;
 }  }
Line 245  schedTimer(sched_root_task_t * __restrict root, sched_ Line 276  schedTimer(sched_root_task_t * __restrict root, sched_
  * @root = root task   * @root = root task
  * @func = task execution function   * @func = task execution function
  * @arg = 1st func argument   * @arg = 1st func argument
 * @... = next func arguments, like u_long * @val = additional func argument
  * return: NULL error or !=NULL new queued task   * return: NULL error or !=NULL new queued task
  */   */
 sched_task_t *  sched_task_t *
schedEvent(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, ...)schedEvent(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long val)
 {  {
         sched_task_t *task;          sched_task_t *task;
         void *ptr;          void *ptr;
         va_list lst;  
   
         if (!root || !func)          if (!root || !func)
                 return NULL;                  return NULL;
   
         /* get new task */          /* get new task */
        if ((task = TAILQ_FIRST(&root->root_unuse)))        if (!(task = _sched_useTask(root)))
                TAILQ_REMOVE(&root->root_unuse, task, task_node);                return NULL;
        else { 
                task = malloc(sizeof(sched_task_t)); 
                if (!task) { 
                        LOGERR; 
                        return NULL; 
                } 
        } 
   
         memset(task, 0, sizeof(sched_task_t));          memset(task, 0, sizeof(sched_task_t));
         task->task_id = 0;          task->task_id = 0;
        task->task_type = taskEVENT;        task->task_lock = 0;
        task->task_root = root; 
         task->task_func = func;          task->task_func = func;
           TASK_TYPE(task) = taskEVENT;
           TASK_ROOT(task) = root;
   
         TASK_ARG(task) = arg;          TASK_ARG(task) = arg;
        va_start(lst, arg);        TASK_VAL(task) = val;
        TASK_VAL(task) = va_arg(lst, u_long); 
        va_end(lst); 
   
         if (root->root_hooks.hook_add.event)          if (root->root_hooks.hook_add.event)
                 ptr = root->root_hooks.hook_add.event(task, NULL);                  ptr = root->root_hooks.hook_add.event(task, NULL);
         else          else
                 ptr = NULL;                  ptr = NULL;
   
        if (!ptr)        if (!ptr) {
 #ifdef HAVE_LIBPTHREAD
                 pthread_mutex_lock(&root->root_mtx[taskEVENT]);
 #endif
                 TAILQ_INSERT_TAIL(&root->root_event, task, task_node);                  TAILQ_INSERT_TAIL(&root->root_event, task, task_node);
        else {#ifdef HAVE_LIBPTHREAD
                task->task_type = taskUNUSE;                pthread_mutex_unlock(&root->root_mtx[taskEVENT]);
                TAILQ_INSERT_TAIL(&root->root_unuse, task, task_node);#endif
                task = NULL;        } else
        }                task = _sched_unuseTask(task);
   
         return task;          return task;
 }  }
Line 302  schedEvent(sched_root_task_t * __restrict root, sched_ Line 327  schedEvent(sched_root_task_t * __restrict root, sched_
  * @root = root task   * @root = root task
  * @func = task execution function   * @func = task execution function
  * @arg = 1st func argument   * @arg = 1st func argument
 * @... = next func arguments, like u_long * @val = additional func argument
  * return: NULL error or !=NULL new queued task   * return: NULL error or !=NULL new queued task
  */   */
 sched_task_t *  sched_task_t *
schedEventLo(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, ...)schedEventLo(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long val)
 {  {
         sched_task_t *task;          sched_task_t *task;
         void *ptr;          void *ptr;
         va_list lst;  
   
         if (!root || !func)          if (!root || !func)
                 return NULL;                  return NULL;
   
         /* get new task */          /* get new task */
        if ((task = TAILQ_FIRST(&root->root_unuse)))        if (!(task = _sched_useTask(root)))
                TAILQ_REMOVE(&root->root_unuse, task, task_node);                return NULL;
        else { 
                task = malloc(sizeof(sched_task_t)); 
                if (!task) { 
                        LOGERR; 
                        return NULL; 
                } 
        } 
   
         memset(task, 0, sizeof(sched_task_t));          memset(task, 0, sizeof(sched_task_t));
         task->task_id = 0;          task->task_id = 0;
        task->task_type = taskEVENT;        task->task_lock = 0;
        task->task_root = root; 
         task->task_func = func;          task->task_func = func;
           TASK_TYPE(task) = taskEVENT;
           TASK_ROOT(task) = root;
   
         TASK_ARG(task) = arg;          TASK_ARG(task) = arg;
        va_start(lst, arg);        TASK_VAL(task) = val;
        TASK_VAL(task) = va_arg(lst, u_long); 
        va_end(lst); 
   
         if (root->root_hooks.hook_add.eventlo)          if (root->root_hooks.hook_add.eventlo)
                 ptr = root->root_hooks.hook_add.eventlo(task, NULL);                  ptr = root->root_hooks.hook_add.eventlo(task, NULL);
         else          else
                 ptr = NULL;                  ptr = NULL;
   
        if (!ptr)        if (!ptr) {
 #ifdef HAVE_LIBPTHREAD
                 pthread_mutex_lock(&root->root_mtx[taskEVENTLO]);
 #endif
                 TAILQ_INSERT_TAIL(&root->root_eventlo, task, task_node);                  TAILQ_INSERT_TAIL(&root->root_eventlo, task, task_node);
        else {#ifdef HAVE_LIBPTHREAD
                task->task_type = taskUNUSE;                pthread_mutex_unlock(&root->root_mtx[taskEVENTLO]);
                TAILQ_INSERT_TAIL(&root->root_unuse, task, task_node);#endif
                task = NULL;        } else
        }                task = _sched_unuseTask(task);
   
         return task;          return task;
 }  }
Line 358  schedEventLo(sched_root_task_t * __restrict root, sche Line 377  schedEventLo(sched_root_task_t * __restrict root, sche
  * @root = root task   * @root = root task
  * @func = task execution function   * @func = task execution function
  * @arg = 1st func argument   * @arg = 1st func argument
 * @... = next func arguments, like u_long * @val = additional func argument
 * return: NULL error or !=NULL new queued task * return: return value from called func
  */   */
 sched_task_t *  sched_task_t *
schedCallOnce(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, ...)schedCallOnce(sched_root_task_t * __restrict root, sched_task_func_t func, void *arg, u_long val)
 {  {
         sched_task_t *task;          sched_task_t *task;
        va_list lst;        void *ret;
   
         if (!root || !func)          if (!root || !func)
                 return NULL;                  return NULL;
   
         /* get new task */          /* get new task */
        if ((task = TAILQ_FIRST(&root->root_unuse)))        if (!(task = _sched_useTask(root)))
                TAILQ_REMOVE(&root->root_unuse, task, task_node);                return NULL;
        else { 
                task = malloc(sizeof(sched_task_t)); 
                if (!task) { 
                        LOGERR; 
                        return NULL; 
                } 
        } 
   
         memset(task, 0, sizeof(sched_task_t));          memset(task, 0, sizeof(sched_task_t));
         task->task_id = 0;          task->task_id = 0;
        task->task_type = taskEVENT;        task->task_lock = 0;
        task->task_root = root; 
         task->task_func = func;          task->task_func = func;
           TASK_TYPE(task) = taskEVENT;
           TASK_ROOT(task) = root;
   
         TASK_ARG(task) = arg;          TASK_ARG(task) = arg;
        va_start(lst, arg);        TASK_VAL(task) = val;
        TASK_VAL(task) = va_arg(lst, u_long); 
        va_end(lst); 
   
        if (schedCall(task)) {        ret = schedCall(task);
                task->task_type = taskUNUSE; 
                TAILQ_INSERT_TAIL(&root->root_unuse, task, task_node); 
                task = NULL; 
        } 
   
        return task;        _sched_unuseTask(task);
         return ret;
 }  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.4.2.1


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