converted nanoseconds to milliseconds if epoll_pwait2() is not avaiable and used epoll_pwait() at the compile time

This commit is contained in:
hyung-hwan 2025-05-04 12:00:01 +09:00
parent a8eec75ce3
commit cf7bdd66fd
2 changed files with 30 additions and 11 deletions

View File

@ -1,2 +1,2 @@
all:
cc -Wall -g -o ctx ctx.c
cc -Wall -g -o ctx ctx.c -lrt

39
ctx.c
View File

@ -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);
}