--- libaitsched/src/aitsched.c 2012/05/10 15:30:18 1.6.2.5 +++ libaitsched/src/aitsched.c 2012/05/30 08:52:45 1.9 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitsched.c,v 1.6.2.5 2012/05/10 15:30:18 misho Exp $ +* $Id: aitsched.c,v 1.9 2012/05/30 08:52:45 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -101,6 +101,7 @@ schedRegisterHooks(sched_root_task_t * __restrict root root->root_hooks.hook_add.read = sched_hook_read; root->root_hooks.hook_add.write = sched_hook_write; + root->root_hooks.hook_add.alarm = sched_hook_alarm; root->root_hooks.hook_exec.cancel = sched_hook_cancel; root->root_hooks.hook_exec.fetch = sched_hook_fetch; @@ -152,6 +153,7 @@ schedInit(void ** __restrict data, size_t datlen) TAILQ_INIT(&root->root_read); TAILQ_INIT(&root->root_write); + TAILQ_INIT(&root->root_alarm); TAILQ_INIT(&root->root_timer); TAILQ_INIT(&root->root_event); TAILQ_INIT(&root->root_eventlo); @@ -204,6 +206,9 @@ schedEnd(sched_root_task_t ** __restrict root) TAILQ_FOREACH_SAFE(task, &(*root)->root_write, task_node, tmp) { schedCancel(task); } + TAILQ_FOREACH_SAFE(task, &(*root)->root_alarm, task_node, tmp) { + schedCancel(task); + } TAILQ_FOREACH_SAFE(task, &(*root)->root_timer, task_node, tmp) { schedCancel(task); } @@ -312,6 +317,9 @@ schedCancel(sched_task_t * __restrict task) case taskWRITE: queue = &TASK_ROOT(task)->root_write; break; + case taskALARM: + queue = &TASK_ROOT(task)->root_alarm; + break; case taskTIMER: queue = &TASK_ROOT(task)->root_timer; break; @@ -347,7 +355,7 @@ schedCancel(sched_task_t * __restrict task) * * @root = root task * @type = cancel from queue type, if =taskMAX cancel same task from all queues - * @criteria = find task by criteria [CRITERIA_CALL|CRITERIA_ARG|CRITERIA_FD|CRITERIA_VAL|CRITERIA_TV] + * @criteria = find task by criteria [CRITERIA_CALL|CRITERIA_ARG|CRITERIA_FD|CRITERIA_VAL|CRITERIA_TS] * @param = search parameter * @hook = custom cleanup hook function, may be NULL * return: -1 error, -2 error in sub-stage cancel execution, -3 error from custom hook or 0 ok @@ -356,9 +364,9 @@ int schedCancelby(sched_root_task_t * __restrict root, sched_task_type_t type, u_char criteria, void *param, sched_hook_func_t hook) { - sched_task_t *task; + sched_task_t *task, *tmp; sched_queue_t *queue; - int flg = 0; + register int flg = 0; if (!root) return -1; @@ -367,6 +375,8 @@ schedCancelby(sched_root_task_t * __restrict root, sch return -2; if (schedCancelby(root, taskWRITE, criteria, param, hook)) return -2; + if (schedCancelby(root, taskALARM, criteria, param, hook)) + return -2; if (schedCancelby(root, taskTIMER, criteria, param, hook)) return -2; if (schedCancelby(root, taskEVENT, criteria, param, hook)) @@ -384,6 +394,9 @@ schedCancelby(sched_root_task_t * __restrict root, sch case taskWRITE: queue = &root->root_write; break; + case taskALARM: + queue = &root->root_alarm; + break; case taskTIMER: queue = &root->root_timer; break; @@ -403,63 +416,60 @@ schedCancelby(sched_root_task_t * __restrict root, sch #ifdef HAVE_LIBPTHREAD pthread_mutex_lock(&root->root_mtx[type]); #endif - TAILQ_FOREACH(task, queue, task_node) - if (criteria == CRITERIA_CALL) { - if (task->task_func == (sched_task_func_t) param) { - flg++; + TAILQ_FOREACH_SAFE(task, queue, task_node, tmp) { + flg ^= flg; + switch (criteria) { + case CRITERIA_CALL: + if (TASK_FUNC(task) == (sched_task_func_t) param) + flg = 1; break; - } - } else if (criteria == CRITERIA_ARG) { - if (task->task_arg == param) { - flg++; + case CRITERIA_ARG: + if (TASK_ARG(task) == param) + flg = 1; break; - } - } else if (criteria == CRITERIA_FD) { - if (TASK_FD(task) == (intptr_t) param) { - flg++; + case CRITERIA_FD: + if (TASK_FD(task) == (intptr_t) param) + flg = 1; break; - } - } else if (criteria == CRITERIA_VAL) { - if (TASK_VAL(task) == (u_long) param) { - flg++; + case CRITERIA_VAL: + if (TASK_VAL(task) == (u_long) param) + flg = 1; break; - } - } else if (criteria == CRITERIA_TV) { - if (!sched_timespeccmp(&TASK_TS(task), (struct timespec*) param, -)) { - flg++; + case CRITERIA_TS: + if (!sched_timespeccmp(&TASK_TS(task), (struct timespec*) param, -)) + flg = 1; break; - } - } else { -#ifdef HAVE_LIBPTHREAD - pthread_mutex_unlock(&root->root_mtx[type]); -#endif - sched_SetErr(EINVAL, "Invalid parameter criteria %d", criteria); - return -1; + default: + sched_SetErr(EINVAL, "Invalid parameter criteria %d", criteria); + flg = -1; } -#ifdef HAVE_LIBPTHREAD - pthread_mutex_unlock(&root->root_mtx[type]); -#endif - if (!flg || !task) /* task not found */ - return 0; + if (flg < 0) + break; + /* cancel choosen task */ + if (flg > 0) { + if (TASK_ROOT(task)->root_hooks.hook_exec.cancel) + if (TASK_ROOT(task)->root_hooks.hook_exec.cancel(task, NULL)) { + flg = -1; + break; + } + /* custom hook */ + if (hook) + if (hook(task, NULL)) { + flg = -3; + break; + } - if (TASK_ROOT(task)->root_hooks.hook_exec.cancel) - if (TASK_ROOT(task)->root_hooks.hook_exec.cancel(task, NULL)) - return -1; - if (hook) - if (hook(task, NULL)) - return -3; + TAILQ_REMOVE(queue, task, task_node); + if (TASK_TYPE(task) != taskUNUSE) + _sched_unuseTask(task); + flg ^= flg; /* ok */ + } + } #ifdef HAVE_LIBPTHREAD - pthread_mutex_lock(&TASK_ROOT(task)->root_mtx[type]); + pthread_mutex_unlock(&root->root_mtx[type]); #endif - TAILQ_REMOVE(queue, task, task_node); -#ifdef HAVE_LIBPTHREAD - pthread_mutex_unlock(&TASK_ROOT(task)->root_mtx[type]); -#endif - - if (TASK_TYPE(task) != taskUNUSE) - _sched_unuseTask(task); - return 0; + return flg; } /*