--- libaitsched/src/hooks.c 2013/11/14 21:37:27 1.24 +++ libaitsched/src/hooks.c 2014/01/27 17:08:02 1.24.4.2 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: hooks.c,v 1.24 2013/11/14 21:37:27 misho Exp $ +* $Id: hooks.c,v 1.24.4.2 2014/01/27 17:08:02 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -62,11 +62,17 @@ sched_hook_init(void *root, void *arg __unused) if (!r) return (void*) -1; +#ifndef KQ_DISABLE r->root_kq = kqueue(); if (r->root_kq == -1) { LOGERR; 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; } @@ -86,10 +92,16 @@ sched_hook_fini(void *root, void *arg __unused) if (!r) return (void*) -1; +#ifndef KQ_DISABLE if (r->root_kq > 2) { close(r->root_kq); 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; } @@ -105,8 +117,13 @@ void * sched_hook_cancel(void *task, void *arg __unused) { sched_task_t *t = task; +#ifndef KQ_DISABLE struct kevent chg[1]; struct timespec timeout = { 0, 0 }; +#else + sched_root_task_t *r = NULL; + register int i; +#endif #ifdef AIO_SUPPORT struct aiocb *acb; #ifdef EVFILT_LIO @@ -117,23 +134,49 @@ sched_hook_cancel(void *task, void *arg __unused) if (!t || !TASK_ROOT(t)) return (void*) -1; +#ifdef KQ_DISABLE + r = TASK_ROOT(t); +#endif switch (TASK_TYPE(t)) { case taskREAD: +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t)); #else EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, (void*) TASK_FD(t)); #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; case taskWRITE: +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t)); #else EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, (void*) TASK_FD(t)); #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; case taskALARM: +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_DELETE, 0, 0, (intptr_t) TASK_DATA(t)); @@ -141,22 +184,28 @@ sched_hook_cancel(void *task, void *arg __unused) EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_DELETE, 0, 0, (void*) TASK_DATA(t)); #endif +#endif break; case taskNODE: +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t)); #else EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, EV_DELETE, 0, 0, (void*) TASK_FD(t)); #endif +#endif break; case taskPROC: +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t)); #else EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, EV_DELETE, 0, 0, (void*) TASK_VAL(t)); #endif +#endif break; case taskSIGNAL: +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t)); #else @@ -164,9 +213,11 @@ sched_hook_cancel(void *task, void *arg __unused) #endif /* restore signal */ signal(TASK_VAL(t), SIG_DFL); +#endif break; #ifdef AIO_SUPPORT case taskAIO: +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], TASK_VAL(t), EVFILT_AIO, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t)); #else @@ -179,9 +230,11 @@ sched_hook_cancel(void *task, void *arg __unused) free(acb); TASK_VAL(t) = 0; } +#endif break; #ifdef EVFILT_LIO case taskLIO: +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], TASK_VAL(t), EVFILT_LIO, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t)); #else @@ -197,16 +250,19 @@ sched_hook_cancel(void *task, void *arg __unused) free(acbs); TASK_VAL(t) = 0; } +#endif break; #endif /* EVFILT_LIO */ #endif /* AIO_SUPPORT */ #ifdef EVFILT_USER case taskUSER: +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t)); #else EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, EV_DELETE, 0, 0, (void*) TASK_VAL(t)); #endif +#endif break; #endif /* EVFILT_USER */ case taskTHREAD: @@ -224,7 +280,9 @@ sched_hook_cancel(void *task, void *arg __unused) return NULL; } +#ifndef KQ_DISABLE kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout); +#endif return NULL; } @@ -275,12 +333,20 @@ void * sched_hook_read(void *task, void *arg __unused) { sched_task_t *t = task; +#ifndef KQ_DISABLE struct kevent chg[1]; struct timespec timeout = { 0, 0 }; +#else + sched_root_task_t *r = NULL; +#endif if (!t || !TASK_ROOT(t)) return (void*) -1; +#ifdef KQ_DISABLE + r = TASK_ROOT(t); +#endif +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_FD(t)); #else @@ -293,6 +359,11 @@ sched_hook_read(void *task, void *arg __unused) LOGERR; 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; } @@ -308,12 +379,20 @@ void * sched_hook_write(void *task, void *arg __unused) { sched_task_t *t = task; +#ifndef KQ_DISABLE struct kevent chg[1]; struct timespec timeout = { 0, 0 }; +#else + sched_root_task_t *r = NULL; +#endif if (!t || !TASK_ROOT(t)) return (void*) -1; +#ifdef KQ_DISABLE + r = TASK_ROOT(t); +#endif +#ifndef KQ_DISABLE #ifdef __NetBSD__ EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_FD(t)); #else @@ -326,6 +405,11 @@ sched_hook_write(void *task, void *arg __unused) LOGERR; 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; } @@ -340,6 +424,7 @@ sched_hook_write(void *task, void *arg __unused) void * sched_hook_alarm(void *task, void *arg __unused) { +#ifndef KQ_DISABLE sched_task_t *t = task; struct kevent chg[1]; struct timespec timeout = { 0, 0 }; @@ -364,6 +449,7 @@ sched_hook_alarm(void *task, void *arg __unused) return (void*) -1; } +#endif return NULL; } @@ -377,6 +463,7 @@ sched_hook_alarm(void *task, void *arg __unused) void * sched_hook_node(void *task, void *arg __unused) { +#ifndef KQ_DISABLE sched_task_t *t = task; struct kevent chg[1]; struct timespec timeout = { 0, 0 }; @@ -401,6 +488,7 @@ sched_hook_node(void *task, void *arg __unused) return (void*) -1; } +#endif return NULL; } @@ -414,6 +502,7 @@ sched_hook_node(void *task, void *arg __unused) void * sched_hook_proc(void *task, void *arg __unused) { +#ifndef KQ_DISABLE sched_task_t *t = task; struct kevent chg[1]; struct timespec timeout = { 0, 0 }; @@ -436,6 +525,7 @@ sched_hook_proc(void *task, void *arg __unused) return (void*) -1; } +#endif return NULL; } @@ -449,6 +539,7 @@ sched_hook_proc(void *task, void *arg __unused) void * sched_hook_signal(void *task, void *arg __unused) { +#ifndef KQ_DISABLE sched_task_t *t = task; struct kevent chg[1]; struct timespec timeout = { 0, 0 }; @@ -472,6 +563,7 @@ sched_hook_signal(void *task, void *arg __unused) return (void*) -1; } +#endif return NULL; } @@ -486,6 +578,7 @@ sched_hook_signal(void *task, void *arg __unused) void * sched_hook_user(void *task, void *arg __unused) { +#ifndef KQ_DISABLE sched_task_t *t = task; struct kevent chg[1]; struct timespec timeout = { 0, 0 }; @@ -508,6 +601,7 @@ sched_hook_user(void *task, void *arg __unused) return (void*) -1; } +#endif return NULL; } #endif @@ -525,8 +619,12 @@ sched_hook_fetch(void *root, void *arg __unused) sched_root_task_t *r = root; sched_task_t *task, *tmp; struct timespec now, m, mtmp; - struct timespec *timeout; +#ifndef KQ_DISABLE struct kevent evt[1], res[KQ_EVENTS]; + struct timespec *timeout, m, mtmp; +#else + struct timeval *timeout, tv; +#endif register int i, flg; int en; #ifdef AIO_SUPPORT @@ -601,7 +699,7 @@ sched_hook_fetch(void *root, void *arg __unused) /* set wait INFTIM */ sched_timespecinf(&r->root_wait); } -#else +#else /* ! TIMER_WITHOUT_SORT */ if (!TAILQ_FIRST(&r->root_task) && (task = TAILQ_FIRST(&r->root_timer))) { clock_gettime(CLOCK_MONOTONIC, &now); @@ -612,18 +710,35 @@ sched_hook_fetch(void *root, void *arg __unused) /* set wait INFTIM */ sched_timespecinf(&r->root_wait); } -#endif +#endif /* TIMER_WITHOUT_SORT */ /* if present member of task, set NOWAIT */ if (TAILQ_FIRST(&r->root_task)) 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; - 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; - else + else { +#ifndef KQ_DISABLE 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) { +#else + if ((en = select(r->root_kq, &r->root_fds[0], &r->root_fds[1], + &r->root_fds[0], timeout)) == -1) { +#endif /* KQ_DISABLE */ if (r->root_hooks.hook_exec.exception) { if (r->root_hooks.hook_exec.exception(r, NULL)) return NULL; @@ -636,6 +751,7 @@ sched_hook_fetch(void *root, void *arg __unused) now.tv_sec = now.tv_nsec = 0; /* Go and catch the cat into pipes ... */ for (i = 0; i < en; i++) { +#ifndef KQ_DISABLE memcpy(evt, &res[i], sizeof evt); evt->flags = EV_DELETE; /* Put read/write task to ready queue */ @@ -1004,7 +1120,9 @@ sched_hook_fetch(void *root, void *arg __unused) } else LOGERR; } - } /* end of kevent dispatcher */ +#else /* end of kevent dispatcher */ +#endif /* KQ_DISABLE */ + } skip_event: /* timer update & put in ready queue */