diff --git a/Makefile b/Makefile index 1a310eb..417c72a 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,2 @@ all: - cc -Wall -g -o ctx ctx.c + cc -Wall -g -o ctx ctx.c -lrt diff --git a/ctx.c b/ctx.c index 765bd39..2bfd111 100644 --- a/ctx.c +++ b/ctx.c @@ -66,6 +66,7 @@ struct hip_uctx_t hip_oow_t cso; /* number of context switches out */ hip_nsecdur_t wakeup_time; + int waiting_fd; unsigned int stid; hip_uctx_link_t uctx; @@ -272,10 +273,11 @@ static void multiplex(hip_uctx_t* uctx, void *ctx) hip = uctx->hip; while (1) { - if (IS_EMPTY(&hip->sleeping)) + if (IS_EMPTY(&hip->sleeping) && IS_EMPTY(&hip->io_waiting)) { // STILL NEED TO HANDLE IO FILE DESCRIPTORS... /* go back to the scheduler */ +printf ("NO SLEEPING. BACK TO SCEDULER\n"); swapcontext(&hip->uctx_mux->uc, &hip->uctx_sched->uc); } else @@ -291,16 +293,28 @@ static void multiplex(hip_uctx_t* uctx, void *ctx) u = UCTX_FROM_LINK(l); now = monotime(); wait = now >= u->wakeup_time? 0: u->wakeup_time - now; - -printf ("WAITING %llu\n", (unsigned long long)wait); - // TODO: support different io multiplexers... - tmout.tv_sec = wait / 1000000000; - tmout.tv_nsec = wait % 1000000000; +/* TODO: the io_waiting process that is time-bound must be catered for */ /* TODO: * lazy removal of unneeded context here??? * epoll_ctl(DELETE here */ + +printf ("WAITING %llu\n", (unsigned long long)wait); + /* TODO: support different io multiplexers...*/ + #if defined(HAVE_EPOLL_PWAIT2) + tmout.tv_sec = wait / 1000000000; + tmout.tv_nsec = wait % 1000000000; n = epoll_pwait2(hip->mux_id, ee, 100, &tmout, HIP_NULL); + #else + /* epoll_pwait()'s timeout is at the resolution of a millisecond. + * add 1 millisecond as long as there is a fraction of nanoseconds + * less than 1 millisecond. + * ceil(wait / 1000000.0) + * (wait / 1000000) + !!(wait % 1000000) + * (wait + 1000000 - 1) / 1000000 + */ + n = epoll_pwait(hip->mux_id, ee, 100, (wait + 1000000 - 1) / 1000000, HIP_NULL); + #endif if (n <= -1) { /* TODO: some error handling action is required */ @@ -312,13 +326,14 @@ printf ("WAITING %llu\n", (unsigned long long)wait); do { l = ee[--n].data.ptr; -printf ("PWAIT link MULTIPLEX %p\n", l); - /*u = UCTX_FROM_LINK(l);*/ + u = UCTX_FROM_LINK(l); UNCHAIN(l); ADD_BACK(l, &hip->runnables); - //epoll_ctl(hip->mux_id, EPOLL_CTL_DEL, +printf ("PWAIT link MULTIPLEX DEL %p fd[%d]\n", l, u->waiting_fd); + +epoll_ctl(hip->mux_id, EPOLL_CTL_DEL, u->waiting_fd, HIP_NULL); } while(n > 0); } @@ -336,7 +351,10 @@ printf ("PWAIT link MULTIPLEX %p\n", l); /* go back to the scheduler */ if (!IS_EMPTY(&hip->runnables)) + { +printf ("BACK TO SCHEDULER \n"); swapcontext(&hip->uctx_mux->uc, &hip->uctx_sched->uc); + } } } } @@ -552,13 +570,14 @@ void hip_awaitio(hip_t* hip, int fd, int flags) if (flags & HIP_IO_READ) ev.events |= EPOLLIN; if (flags & HIP_IO_WRITE) ev.events |= EPOLLOUT; ev.data.ptr = hip->running; /* store running context link */ -printf ("PWAIT link ADD %p\n", ev.data.ptr); +printf ("PWAIT link ADD %p fd[%d]\n", ev.data.ptr, fd); epoll_ctl(hip->mux_id, EPOLL_CTL_ADD, fd, &ev); /* TODO: error handling - probably panic? */ rr = UCTX_FROM_LINK(hip->running); ADD_BACK(hip->running, &hip->io_waiting); hip->running = HIP_NULL; + rr->waiting_fd = fd; /* remember the file descriptor being waited on */ swapcontext(&rr->uc, &hip->uctx_sched->uc); }