|
|
| version 1.27.2.7, 2014/06/03 20:42:48 | version 1.28, 2014/06/05 22:37:29 |
|---|---|
| Line 56 transit_task2ready(sched_task_t * __restrict t, sched_ | Line 56 transit_task2ready(sched_task_t * __restrict t, sched_ |
| insert_task_to(t, &(TASK_ROOT(t))->root_ready); | insert_task_to(t, &(TASK_ROOT(t))->root_ready); |
| } | } |
| #ifdef HAVE_LIBPTHREAD | |
| static void * | |
| _sched_threadWrapper(sched_task_t *t) | |
| { | |
| void *ret = NULL; | |
| sched_root_task_t *r; | |
| if (!t || !TASK_ROOT(t)) | |
| pthread_exit(ret); | |
| else | |
| r = (sched_root_task_t*) TASK_ROOT(t); | |
| pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); | |
| /* | |
| pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); | |
| */ | |
| /* notify parent, thread is ready for execution */ | |
| pthread_testcancel(); | |
| ret = schedCall(t); | |
| r->root_ret = ret; | |
| if (TASK_VAL(t)) { | |
| transit_task2unuse(t, &r->root_thread); | |
| TASK_VAL(t) = 0; | |
| } | |
| pthread_exit(ret); | |
| } | |
| #endif | |
| #if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) && defined(HAVE_TIMER_DELETE) | |
| #if SUP_ENABLE == KQ_SUPPORT | |
| static void * | |
| _sched_rtcWrapper(sched_task_t *t) | |
| { | |
| sched_task_t *task; | |
| void *ret; | |
| if (!t || !TASK_ROOT(t) || !TASK_DATA(t)) | |
| return NULL; | |
| else { | |
| task = (sched_task_t*) TASK_DATA(t); | |
| timer_delete((timer_t) TASK_DATLEN(t)); | |
| } | |
| ret = schedCall(task); | |
| transit_task2unuse(task, &(TASK_ROOT(task))->root_rtc); | |
| return ret; | |
| } | |
| #else | |
| static void | |
| _sched_rtcSigWrapper(int sig, siginfo_t *si, void *uc) | |
| { | |
| sched_task_t *task; | |
| if (si && si->si_value.sival_ptr) { | |
| task = (sched_task_t*) si->si_value.sival_ptr; | |
| timer_delete((timer_t) TASK_FLAG(task)); | |
| TASK_RET(task) = (intptr_t) schedCall(task); | |
| transit_task2unuse(task, &(TASK_ROOT(task))->root_rtc); | |
| } | |
| } | |
| #endif | |
| #endif | |
| /* | /* |
| * sched_hook_init() - Default INIT hook | * sched_hook_init() - Default INIT hook |
| * | * |
| Line 303 sched_hook_cancel(void *task, void *arg __unused) | Line 373 sched_hook_cancel(void *task, void *arg __unused) |
| 0, 0, (void*) TASK_VAL(t)); | 0, 0, (void*) TASK_VAL(t)); |
| #endif | #endif |
| /* restore signal */ | /* restore signal */ |
| signal(TASK_VAL(t), SIG_DFL); | if (flg < 2) |
| signal(TASK_VAL(t), SIG_DFL); | |
| #endif | #endif |
| break; | break; |
| #ifdef AIO_SUPPORT | #ifdef AIO_SUPPORT |
| Line 398 sched_hook_cancel(void *task, void *arg __unused) | Line 469 sched_hook_cancel(void *task, void *arg __unused) |
| #if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) && defined(HAVE_TIMER_DELETE) | #if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) && defined(HAVE_TIMER_DELETE) |
| case taskRTC: | case taskRTC: |
| timer_delete((timer_t) TASK_FLAG(t)); | timer_delete((timer_t) TASK_FLAG(t)); |
| #if SUP_ENABLE == KQ_SUPPORT | |
| schedCancel((sched_task_t*) TASK_RET(t)); | schedCancel((sched_task_t*) TASK_RET(t)); |
| #else | |
| /* check for multi subscribers */ | |
| flg = 0; | |
| TAILQ_FOREACH_SAFE(tt, &r->root_rtc, task_node, tmp) | |
| if (TASK_DATA(tt) != TASK_DATA(t)) | |
| continue; | |
| else | |
| flg++; | |
| /* restore signal */ | |
| if (flg < 2) | |
| signal((intptr_t) TASK_DATA(t) + SIGRTMIN, SIG_DFL); | |
| #endif | |
| return NULL; | return NULL; |
| #endif /* HAVE_TIMER_CREATE */ | #endif /* HAVE_TIMER_CREATE */ |
| default: | default: |
| Line 726 sched_hook_signal(void *task, void *arg __unused) | Line 811 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 | #endif |
| return NULL; | return NULL; |
| } | } |
| Line 792 static inline void | Line 859 static inline void |
| fetch_hook_kevent_proceed(int en, struct kevent *res, sched_root_task_t *r) | fetch_hook_kevent_proceed(int en, struct kevent *res, sched_root_task_t *r) |
| { | { |
| struct kevent evt[1]; | struct kevent evt[1]; |
| register int i, flg; | register int i; |
| sched_task_t *task, *tmp; | sched_task_t *task, *tmp; |
| struct timespec now = { 0, 0 }; | struct timespec now = { 0, 0 }; |
| #ifdef AIO_SUPPORT | #ifdef AIO_SUPPORT |
| Line 813 fetch_hook_kevent_proceed(int en, struct kevent *res, | Line 880 fetch_hook_kevent_proceed(int en, struct kevent *res, |
| /* Put read/write task to ready queue */ | /* Put read/write task to ready queue */ |
| switch (res[i].filter) { | switch (res[i].filter) { |
| case EVFILT_READ: | case EVFILT_READ: |
| flg = 0; | |
| TAILQ_FOREACH_SAFE(task, &r->root_read, task_node, tmp) { | TAILQ_FOREACH_SAFE(task, &r->root_read, task_node, tmp) { |
| if (TASK_FD(task) != ((intptr_t) res[i].udata)) | if (TASK_FD(task) != ((intptr_t) res[i].udata)) |
| continue; | continue; |
| else { | else { |
| flg++; | |
| TASK_RET(task) = res[i].data; | TASK_RET(task) = res[i].data; |
| TASK_FLAG(task) = (u_long) res[i].fflags; | TASK_FLAG(task) = (u_long) res[i].fflags; |
| } | } |
| Line 838 fetch_hook_kevent_proceed(int en, struct kevent *res, | Line 903 fetch_hook_kevent_proceed(int en, struct kevent *res, |
| insert_task_to(task, &r->root_ready); | insert_task_to(task, &r->root_ready); |
| } | } |
| } | } |
| /* if match at least 2, don't remove resouce of event */ | |
| if (flg > 1) | |
| evt->flags ^= evt->flags; | |
| break; | break; |
| case EVFILT_WRITE: | case EVFILT_WRITE: |
| flg = 0; | |
| TAILQ_FOREACH_SAFE(task, &r->root_write, task_node, tmp) { | TAILQ_FOREACH_SAFE(task, &r->root_write, task_node, tmp) { |
| if (TASK_FD(task) != ((intptr_t) res[i].udata)) | if (TASK_FD(task) != ((intptr_t) res[i].udata)) |
| continue; | continue; |
| else { | else { |
| flg++; | |
| TASK_RET(task) = res[i].data; | TASK_RET(task) = res[i].data; |
| TASK_FLAG(task) = (u_long) res[i].fflags; | TASK_FLAG(task) = (u_long) res[i].fflags; |
| } | } |
| Line 868 fetch_hook_kevent_proceed(int en, struct kevent *res, | Line 928 fetch_hook_kevent_proceed(int en, struct kevent *res, |
| insert_task_to(task, &r->root_ready); | insert_task_to(task, &r->root_ready); |
| } | } |
| } | } |
| /* if match at least 2, don't remove resouce of event */ | |
| if (flg > 1) | |
| evt->flags ^= evt->flags; | |
| break; | break; |
| case EVFILT_TIMER: | case EVFILT_TIMER: |
| flg = 0; | |
| TAILQ_FOREACH_SAFE(task, &r->root_alarm, task_node, tmp) { | TAILQ_FOREACH_SAFE(task, &r->root_alarm, task_node, tmp) { |
| if ((uintptr_t) TASK_DATA(task) != ((uintptr_t) res[i].udata)) | if ((uintptr_t) TASK_DATA(task) != ((uintptr_t) res[i].udata)) |
| continue; | continue; |
| else { | else { |
| flg++; | |
| TASK_RET(task) = res[i].data; | TASK_RET(task) = res[i].data; |
| TASK_FLAG(task) = (u_long) res[i].fflags; | TASK_FLAG(task) = (u_long) res[i].fflags; |
| } | } |
| /* remove alarm handle */ | /* remove alarm handle */ |
| transit_task2ready(task, &r->root_alarm); | transit_task2ready(task, &r->root_alarm); |
| } | } |
| /* if match at least 2, don't remove resouce of event */ | |
| if (flg > 1) | |
| evt->flags ^= evt->flags; | |
| break; | break; |
| case EVFILT_VNODE: | case EVFILT_VNODE: |
| flg = 0; | |
| TAILQ_FOREACH_SAFE(task, &r->root_node, task_node, tmp) { | TAILQ_FOREACH_SAFE(task, &r->root_node, task_node, tmp) { |
| if (TASK_FD(task) != ((intptr_t) res[i].udata)) | if (TASK_FD(task) != ((intptr_t) res[i].udata)) |
| continue; | continue; |
| else { | else { |
| flg++; | |
| TASK_RET(task) = res[i].data; | TASK_RET(task) = res[i].data; |
| TASK_FLAG(task) = (u_long) res[i].fflags; | TASK_FLAG(task) = (u_long) res[i].fflags; |
| } | } |
| /* remove node handle */ | /* remove node handle */ |
| transit_task2ready(task, &r->root_node); | transit_task2ready(task, &r->root_node); |
| } | } |
| /* if match at least 2, don't remove resouce of event */ | |
| if (flg > 1) | |
| evt->flags ^= evt->flags; | |
| break; | break; |
| case EVFILT_PROC: | case EVFILT_PROC: |
| flg = 0; | |
| TAILQ_FOREACH_SAFE(task, &r->root_proc, task_node, tmp) { | TAILQ_FOREACH_SAFE(task, &r->root_proc, task_node, tmp) { |
| if (TASK_VAL(task) != ((uintptr_t) res[i].udata)) | if (TASK_VAL(task) != ((uintptr_t) res[i].udata)) |
| continue; | continue; |
| else { | else { |
| flg++; | |
| TASK_RET(task) = res[i].data; | TASK_RET(task) = res[i].data; |
| TASK_FLAG(task) = (u_long) res[i].fflags; | TASK_FLAG(task) = (u_long) res[i].fflags; |
| } | } |
| /* remove proc handle */ | /* remove proc handle */ |
| transit_task2ready(task, &r->root_proc); | transit_task2ready(task, &r->root_proc); |
| } | } |
| /* if match at least 2, don't remove resouce of event */ | |
| if (flg > 1) | |
| evt->flags ^= evt->flags; | |
| break; | break; |
| case EVFILT_SIGNAL: | case EVFILT_SIGNAL: |
| flg = 0; | |
| TAILQ_FOREACH_SAFE(task, &r->root_signal, task_node, tmp) { | TAILQ_FOREACH_SAFE(task, &r->root_signal, task_node, tmp) { |
| if (TASK_VAL(task) != ((uintptr_t) res[i].udata)) | if (TASK_VAL(task) != ((uintptr_t) res[i].udata)) |
| continue; | continue; |
| else { | else { |
| flg++; | |
| TASK_RET(task) = res[i].data; | TASK_RET(task) = res[i].data; |
| TASK_FLAG(task) = (u_long) res[i].fflags; | TASK_FLAG(task) = (u_long) res[i].fflags; |
| } | } |
| /* remove signal handle */ | /* remove signal handle */ |
| transit_task2ready(task, &r->root_signal); | transit_task2ready(task, &r->root_signal); |
| } | } |
| /* if match at least 2, don't remove resouce of event */ | |
| if (flg > 1) | |
| evt->flags ^= evt->flags; | |
| break; | break; |
| #ifdef AIO_SUPPORT | #ifdef AIO_SUPPORT |
| case EVFILT_AIO: | case EVFILT_AIO: |
| flg = 0; | |
| TAILQ_FOREACH_SAFE(task, &r->root_aio, task_node, tmp) { | TAILQ_FOREACH_SAFE(task, &r->root_aio, task_node, tmp) { |
| acb = (struct aiocb*) TASK_VAL(task); | acb = (struct aiocb*) TASK_VAL(task); |
| if (acb != ((struct aiocb*) res[i].udata)) | if (acb != ((struct aiocb*) res[i].udata)) |
| continue; | continue; |
| else { | else { |
| flg++; | |
| TASK_RET(task) = res[i].data; | TASK_RET(task) = res[i].data; |
| TASK_FLAG(task) = (u_long) res[i].fflags; | TASK_FLAG(task) = (u_long) res[i].fflags; |
| } | } |
| Line 965 fetch_hook_kevent_proceed(int en, struct kevent *res, | Line 1000 fetch_hook_kevent_proceed(int en, struct kevent *res, |
| TASK_DATLEN(task) = (u_long) len; | TASK_DATLEN(task) = (u_long) len; |
| TASK_FD(task) = fd; | TASK_FD(task) = fd; |
| } | } |
| /* if match at least 2, don't remove resouce of event */ | |
| if (flg > 1) | |
| evt->flags ^= evt->flags; | |
| break; | break; |
| #ifdef EVFILT_LIO | #ifdef EVFILT_LIO |
| case EVFILT_LIO: | case EVFILT_LIO: |
| flg = 0; | |
| TAILQ_FOREACH_SAFE(task, &r->root_lio, task_node, tmp) { | TAILQ_FOREACH_SAFE(task, &r->root_lio, task_node, tmp) { |
| acbs = (struct aiocb**) TASK_VAL(task); | acbs = (struct aiocb**) TASK_VAL(task); |
| if (acbs != ((struct aiocb**) res[i].udata)) | if (acbs != ((struct aiocb**) res[i].udata)) |
| continue; | continue; |
| else { | else { |
| flg++; | |
| TASK_RET(task) = res[i].data; | TASK_RET(task) = res[i].data; |
| TASK_FLAG(task) = (u_long) res[i].fflags; | TASK_FLAG(task) = (u_long) res[i].fflags; |
| } | } |
| Line 1001 fetch_hook_kevent_proceed(int en, struct kevent *res, | Line 1031 fetch_hook_kevent_proceed(int en, struct kevent *res, |
| if (lseek(fd, off + len, SEEK_CUR) == -1) | if (lseek(fd, off + len, SEEK_CUR) == -1) |
| LOGERR; | LOGERR; |
| } | } |
| /* if match at least 2, don't remove resouce of event */ | |
| if (flg > 1) | |
| evt->flags ^= evt->flags; | |
| break; | break; |
| #endif /* EVFILT_LIO */ | #endif /* EVFILT_LIO */ |
| #endif /* AIO_SUPPORT */ | #endif /* AIO_SUPPORT */ |
| #ifdef EVFILT_USER | #ifdef EVFILT_USER |
| case EVFILT_USER: | case EVFILT_USER: |
| flg = 0; | |
| TAILQ_FOREACH_SAFE(task, &r->root_user, task_node, tmp) { | TAILQ_FOREACH_SAFE(task, &r->root_user, task_node, tmp) { |
| if (TASK_VAL(task) != ((uintptr_t) res[i].udata)) | if (TASK_VAL(task) != ((uintptr_t) res[i].udata)) |
| continue; | continue; |
| else { | else { |
| flg++; | |
| TASK_RET(task) = res[i].data; | TASK_RET(task) = res[i].data; |
| TASK_FLAG(task) = (u_long) res[i].fflags; | TASK_FLAG(task) = (u_long) res[i].fflags; |
| } | } |
| /* remove user handle */ | /* remove user handle */ |
| transit_task2ready(task, &r->root_user); | transit_task2ready(task, &r->root_user); |
| } | } |
| /* if match at least 2, don't remove resouce of event */ | |
| if (flg > 1) | |
| evt->flags ^= evt->flags; | |
| break; | break; |
| #endif /* EVFILT_USER */ | #endif /* EVFILT_USER */ |
| } | } |
| Line 1173 fetch_hook_select_proceed(int en, fd_set rfd, fd_set w | Line 1195 fetch_hook_select_proceed(int en, fd_set rfd, fd_set w |
| insert_task_to(task, &r->root_ready); | insert_task_to(task, &r->root_ready); |
| } | } |
| } | } |
| /* if match equal to 1, remove resouce */ | /* remove resouce */ |
| if (flg == 1) | if (flg) |
| FD_CLR(i, &r->root_fds[0]); | FD_CLR(i, &r->root_fds[0]); |
| } | } |
| Line 1204 fetch_hook_select_proceed(int en, fd_set rfd, fd_set w | Line 1226 fetch_hook_select_proceed(int en, fd_set rfd, fd_set w |
| insert_task_to(task, &r->root_ready); | insert_task_to(task, &r->root_ready); |
| } | } |
| } | } |
| /* if match equal to 1, remove resouce */ | /* remove resouce */ |
| if (flg == 1) | if (flg) |
| FD_CLR(i, &r->root_fds[1]); | FD_CLR(i, &r->root_fds[1]); |
| } | } |
| } | } |
| Line 1438 sched_hook_rtc(void *task, void *arg __unused) | Line 1460 sched_hook_rtc(void *task, void *arg __unused) |
| struct itimerspec its; | struct itimerspec its; |
| struct sigevent evt; | struct sigevent evt; |
| timer_t tmr; | timer_t tmr; |
| #if SUP_ENABLE != KQ_SUPPORT | |
| struct sigaction sa; | |
| #endif | |
| if (!t || !TASK_ROOT(t)) | if (!t || !TASK_ROOT(t)) |
| return (void*) -1; | return (void*) -1; |
| Line 1445 sched_hook_rtc(void *task, void *arg __unused) | Line 1470 sched_hook_rtc(void *task, void *arg __unused) |
| memset(&evt, 0, sizeof evt); | memset(&evt, 0, sizeof evt); |
| evt.sigev_notify = SIGEV_SIGNAL; | evt.sigev_notify = SIGEV_SIGNAL; |
| evt.sigev_signo = (intptr_t) TASK_DATA(t) + SIGRTMIN; | evt.sigev_signo = (intptr_t) TASK_DATA(t) + SIGRTMIN; |
| evt.sigev_value.sival_ptr = TASK_DATA(t); | evt.sigev_value.sival_ptr = t; |
| if (timer_create(CLOCK_MONOTONIC, &evt, &tmr) == -1) { | if (timer_create(CLOCK_MONOTONIC, &evt, &tmr) == -1) { |
| if (TASK_ROOT(t)->root_hooks.hook_exec.exception) | if (TASK_ROOT(t)->root_hooks.hook_exec.exception) |
| Line 1456 sched_hook_rtc(void *task, void *arg __unused) | Line 1481 sched_hook_rtc(void *task, void *arg __unused) |
| } else | } else |
| TASK_FLAG(t) = (u_long) tmr; | TASK_FLAG(t) = (u_long) tmr; |
| #if SUP_ENABLE == KQ_SUPPORT | |
| if (!(sigt = schedSignal(TASK_ROOT(t), _sched_rtcWrapper, TASK_ARG(t), evt.sigev_signo, | if (!(sigt = schedSignal(TASK_ROOT(t), _sched_rtcWrapper, TASK_ARG(t), evt.sigev_signo, |
| t, (size_t) tmr))) { | t, (size_t) tmr))) { |
| if (TASK_ROOT(t)->root_hooks.hook_exec.exception) | if (TASK_ROOT(t)->root_hooks.hook_exec.exception) |
| Line 1466 sched_hook_rtc(void *task, void *arg __unused) | Line 1492 sched_hook_rtc(void *task, void *arg __unused) |
| return (void*) -1; | return (void*) -1; |
| } else | } else |
| TASK_RET(t) = (uintptr_t) sigt; | TASK_RET(t) = (uintptr_t) sigt; |
| #else | |
| memset(&sa, 0, sizeof sa); | |
| sigemptyset(&sa.sa_mask); | |
| sa.sa_sigaction = _sched_rtcSigWrapper; | |
| sa.sa_flags = SA_SIGINFO | SA_RESTART; | |
| if (sigaction(evt.sigev_signo, &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; | |
| timer_delete(tmr); | |
| return (void*) -1; | |
| } | |
| #endif | |
| memset(&its, 0, sizeof its); | memset(&its, 0, sizeof its); |
| its.it_value.tv_sec = t->task_val.ts.tv_sec; | its.it_value.tv_sec = t->task_val.ts.tv_sec; |