From d36fc2b235ddaaa3fbb84a46ef520a0a207293df Mon Sep 17 00:00:00 2001 From: Dmitry Kozlov Date: Mon, 22 Sep 2014 21:48:17 +0400 Subject: triton: make level triggered events oneshot (EPOLLONESHOT) --- accel-pppd/triton/md.c | 44 ++++++++++++++++++++++++++++++++++++-------- accel-pppd/triton/timer.c | 2 ++ accel-pppd/triton/triton.c | 6 +++++- accel-pppd/triton/triton_p.h | 5 ++++- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/accel-pppd/triton/md.c b/accel-pppd/triton/md.c index 1396d3e..6067ff2 100644 --- a/accel-pppd/triton/md.c +++ b/accel-pppd/triton/md.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "triton_p.h" @@ -32,6 +33,8 @@ int md_init(void) return -1; } + fcntl(epoll_fd, F_SETFD, O_CLOEXEC); + epoll_events = _malloc(max_events * sizeof(struct epoll_event)); if (!epoll_events) { fprintf(stderr,"md:cann't allocate memory\n"); @@ -171,15 +174,22 @@ int __export triton_md_enable_handler(struct triton_md_handler_t *ud, int mode) if (mode & MD_MODE_WRITE) h->epoll_event.events |= EPOLLOUT; - if (!h->trig_level) + if (h->trig_level) + h->epoll_event.events |= EPOLLONESHOT; + else h->epoll_event.events |= EPOLLET; if (events == h->epoll_event.events) return 0; - if (events) - r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event); - else + if (events) { + if (h->armed) + r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event); + else { + h->mod = 1; + r = 0; + } + } else r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, h->ud->fd, &h->epoll_event); if (r) { @@ -204,13 +214,21 @@ int __export triton_md_disable_handler(struct triton_md_handler_t *ud,int mode) if (mode & MD_MODE_WRITE) h->epoll_event.events &= ~EPOLLOUT; + if (!(h->epoll_event.events & (EPOLLIN | EPOLLOUT))) + h->epoll_event.events = 0; + if (events == h->epoll_event.events) return 0; - if (h->epoll_event.events & (EPOLLIN | EPOLLOUT)) - r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event); - else { - h->epoll_event.events = 0; + if (h->epoll_event.events) { + if (h->armed) + r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event); + else { + h->mod = 1; + r = 0; + } + } else { + h->mod = 0; r = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, h->ud->fd, NULL); } @@ -228,3 +246,13 @@ void __export triton_md_set_trig(struct triton_md_handler_t *ud, int mode) h->trig_level = mode; } +void md_rearm(struct _triton_md_handler_t *h) +{ + if (h->mod) { + epoll_ctl(epoll_fd, EPOLL_CTL_MOD, h->ud->fd, &h->epoll_event); + h->mod = 0; + } + + h->armed = 1; +} + diff --git a/accel-pppd/triton/timer.c b/accel-pppd/triton/timer.c index d0ebcb4..1e4f061 100644 --- a/accel-pppd/triton/timer.c +++ b/accel-pppd/triton/timer.c @@ -39,6 +39,8 @@ int timer_init(void) return -1; } + fcntl(epoll_fd, F_SETFD, O_CLOEXEC); + epoll_events = _malloc(max_events * sizeof(struct epoll_event)); if (!epoll_events) { fprintf(stderr,"timer: cannot allocate memory\n"); diff --git a/accel-pppd/triton/triton.c b/accel-pppd/triton/triton.c index 5d6f31d..f550db2 100644 --- a/accel-pppd/triton/triton.c +++ b/accel-pppd/triton/triton.c @@ -207,9 +207,11 @@ static void ctx_thread(struct _triton_context_t *ctx) h->pending = 0; events = h->trig_epoll_events; spin_unlock(&ctx->lock); - + __sync_sub_and_fetch(&triton_stat.md_handler_pending, 1); + h->armed = 0; + if ((events & (EPOLLIN | EPOLLERR | EPOLLHUP)) && (h->epoll_event.events & EPOLLIN)) { if (h->ud && h->ud->read) { if (h->ud->read(h->ud)) @@ -224,6 +226,8 @@ static void ctx_thread(struct _triton_context_t *ctx) } } + md_rearm(h); + continue; } diff --git a/accel-pppd/triton/triton_p.h b/accel-pppd/triton/triton_p.h index 9401729..2bbccbd 100644 --- a/accel-pppd/triton/triton_p.h +++ b/accel-pppd/triton/triton_p.h @@ -54,8 +54,10 @@ struct _triton_md_handler_t struct _triton_context_t *ctx; struct epoll_event epoll_event; uint32_t trig_epoll_events; - int pending:1; + int pending; int trig_level:1; + int armed:1; + int mod:1; struct triton_md_handler_t *ud; }; @@ -98,6 +100,7 @@ int event_init(); void md_run(); void md_terminate(); +void md_rearm(struct _triton_md_handler_t *h); void timer_run(); void timer_terminate(); extern struct triton_context_t default_ctx; -- cgit v1.2.3