[qpid-proton] branch master updated: PROTON-2291: Reduce size of epoll proactor connections - Remove unnecessary proactor back pointer from psocket
This is an automated email from the ASF dual-hosted git repository. astitcher pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/qpid-proton.git The following commit(s) were added to refs/heads/master by this push: new 846d403 PROTON-2291: Reduce size of epoll proactor connections - Remove unnecessary proactor back pointer from psocket 846d403 is described below commit 846d403b80a2a1e60d83146ad849230eca04918f Author: Andrew Stitcher AuthorDate: Tue Oct 20 19:21:49 2020 -0400 PROTON-2291: Reduce size of epoll proactor connections - Remove unnecessary proactor back pointer from psocket --- c/src/proactor/epoll-internal.h | 7 +++ c/src/proactor/epoll.c| 35 +-- c/src/proactor/epoll_raw_connection.c | 10 +- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/c/src/proactor/epoll-internal.h b/c/src/proactor/epoll-internal.h index b14b485..66fb15e 100644 --- a/c/src/proactor/epoll-internal.h +++ b/c/src/proactor/epoll-internal.h @@ -212,16 +212,15 @@ struct pn_proactor_t { /* common to connection and listener */ typedef struct psocket_t { - pn_proactor_t *proactor; - // Remaining protected by the pconnection/listener mutex + // Protected by the pconnection/listener mutex epoll_extended_t epoll_io; uint32_t sched_io_events; uint32_t working_io_events; } psocket_t; typedef struct pconnection_t { - psocket_t psocket; pcontext_t context; + psocket_t psocket; pni_timer_t *timer; const char *host, *port; uint32_t new_events; @@ -357,7 +356,7 @@ bool wake(pcontext_t *ctx); void wake_notify(pcontext_t *ctx); void wake_done(pcontext_t *ctx); -void psocket_init(psocket_t* ps, pn_proactor_t* p, epoll_type_t type); +void psocket_init(psocket_t* ps, epoll_type_t type); bool start_polling(epoll_extended_t *ee, int epollfd); void stop_polling(epoll_extended_t *ee, int epollfd); void rearm_polling(epoll_extended_t *ee, int epollfd); diff --git a/c/src/proactor/epoll.c b/c/src/proactor/epoll.c index a2d0864..d2822b4 100644 --- a/c/src/proactor/epoll.c +++ b/c/src/proactor/epoll.c @@ -533,13 +533,12 @@ static void make_runnable(pcontext_t *ctx) { -void psocket_init(psocket_t* ps, pn_proactor_t* p, epoll_type_t type) +void psocket_init(psocket_t* ps, epoll_type_t type) { ps->epoll_io.fd = -1; ps->epoll_io.type = type; ps->epoll_io.wanted = 0; ps->epoll_io.polling = false; - ps->proactor = p; } @@ -675,7 +674,7 @@ static acceptor_t *acceptor_list_next(acceptor_t **start) { // Add an overflowing acceptor to the overflow list. Called with listener context lock held. static void acceptor_set_overflow(acceptor_t *a) { a->overflowed = true; - pn_proactor_t *p = a->psocket.proactor; + pn_proactor_t *p = a->listener->context.proactor; lock(&p->overflow_mutex); acceptor_list_append(&p->overflow, a); unlock(&p->overflow_mutex); @@ -740,7 +739,7 @@ static const char *pconnection_setup(pconnection_t *pc, pn_proactor_t *p, pn_con pcontext_init(&pc->context, PCONNECTION, p); - psocket_init(&pc->psocket, p, PCONNECTION_IO); + psocket_init(&pc->psocket, PCONNECTION_IO); pni_parse_addr(addr, pc->addr_buf, addrlen+1, &pc->host, &pc->port); pc->new_events = 0; pc->wake_count = 0; @@ -804,9 +803,9 @@ static void pconnection_final_free(pconnection_t *pc) { static void pconnection_cleanup(pconnection_t *pc) { assert(pconnection_is_final(pc)); int fd = pc->psocket.epoll_io.fd; - stop_polling(&pc->psocket.epoll_io, pc->psocket.proactor->epollfd); + stop_polling(&pc->psocket.epoll_io, pc->context.proactor->epollfd); if (fd != -1) -pclosefd(pc->psocket.proactor, fd); +pclosefd(pc->context.proactor, fd); lock(&pc->context.mutex); bool can_free = proactor_remove(&pc->context); @@ -945,7 +944,7 @@ static int pconnection_rearm_check(pconnection_t *pc) { static inline void pconnection_rearm(pconnection_t *pc, int wanted_now) { lock(&pc->rearm_mutex); pc->current_arm = pc->psocket.epoll_io.wanted = wanted_now; - rearm(pc->psocket.proactor, &pc->psocket.epoll_io); + rearm(pc->context.proactor, &pc->psocket.epoll_io); unlock(&pc->rearm_mutex); // Return immediately. pc may have just been freed by another thread. } @@ -1314,7 +1313,7 @@ void pconnection_connected_lh(pconnection_t *pc) { /* multi-address connections may call pconnection_start multiple times with diffferent FDs */ static void pconnection_start(pconnection_t *pc, int fd) { - int efd = pc->psocket.proactor->epollfd; + int efd = pc->context.proactor->epollfd; /* Get the local socket name now, get the peer name in pconnection_connected */ socklen_t len = sizeof(pc->local.ss); (void)getsockname(fd, (struct sockaddr*)&pc->local.ss, &len); @@ -1323,7 +1322,7 @@ static void pconnection_start(pconnection_t *pc, int fd) { if (ee->polling) { /* This is not the first attempt, stop polling and close the old FD
[qpid-proton] branch master updated: PROTON-1496: epoll proactor - improved timers implementation with single timerfd kernel resource
This is an automated email from the ASF dual-hosted git repository. cliffjansen pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/qpid-proton.git The following commit(s) were added to refs/heads/master by this push: new d31ad96 PROTON-1496: epoll proactor - improved timers implementation with single timerfd kernel resource d31ad96 is described below commit d31ad9652a1a63f856ed10772e362b4a155ecbf4 Author: Cliff Jansen AuthorDate: Sun Nov 8 11:56:58 2020 -0800 PROTON-1496: epoll proactor - improved timers implementation with single timerfd kernel resource --- c/CMakeLists.txt | 2 +- c/src/proactor/epoll-internal.h | 62 -- c/src/proactor/epoll.c| 338 -- c/src/proactor/epoll_raw_connection.c | 1 + c/src/proactor/epoll_timer.c | 380 ++ 5 files changed, 510 insertions(+), 273 deletions(-) diff --git a/c/CMakeLists.txt b/c/CMakeLists.txt index 2967176..99e328b 100644 --- a/c/CMakeLists.txt +++ b/c/CMakeLists.txt @@ -340,7 +340,7 @@ if (PROACTOR STREQUAL "epoll" OR (NOT PROACTOR AND NOT BUILD_PROACTOR)) check_symbol_exists(epoll_wait "sys/epoll.h" HAVE_EPOLL) if (HAVE_EPOLL) set (PROACTOR_OK epoll) -set (qpid-proton-proactor src/proactor/epoll.c src/proactor/epoll_raw_connection.c ${qpid-proton-proactor-common}) +set (qpid-proton-proactor src/proactor/epoll.c src/proactor/epoll_raw_connection.c src/proactor/epoll_timer.c ${qpid-proton-proactor-common}) set (PROACTOR_LIBS Threads::Threads ${TIME_LIB}) endif() endif() diff --git a/c/src/proactor/epoll-internal.h b/c/src/proactor/epoll-internal.h index 1b8edd3..b14b485 100644 --- a/c/src/proactor/epoll-internal.h +++ b/c/src/proactor/epoll-internal.h @@ -54,14 +54,14 @@ extern "C" { typedef struct acceptor_t acceptor_t; typedef struct tslot_t tslot_t; typedef pthread_mutex_t pmutex; +typedef struct pni_timer_t pni_timer_t; typedef enum { WAKE, /* see if any work to do in proactor/psocket context */ - PCONNECTION_IO, - PCONNECTION_TIMER, LISTENER_IO, - PROACTOR_TIMER, - RAW_CONNECTION_IO + PCONNECTION_IO, + RAW_CONNECTION_IO, + TIMER } epoll_type_t; // Data to use with epoll. @@ -73,19 +73,12 @@ typedef struct epoll_extended_t { pmutex barrier_mutex; } epoll_extended_t; -typedef struct ptimer_t { - pmutex mutex; - epoll_extended_t epoll_io; - bool timer_active; - bool in_doubt; // 0 or 1 callbacks are possible - bool shutting_down; -} ptimer_t; - typedef enum { PROACTOR, PCONNECTION, LISTENER, - RAW_CONNECTION + RAW_CONNECTION, + TIMER_MANAGER } pcontext_type_t; typedef struct pcontext_t { @@ -137,13 +130,24 @@ struct tslot_t { unsigned int earmark_override_gen; }; +typedef struct pni_timer_manager_t { + pcontext_t context; + epoll_extended_t epoll_timer; + pmutex deletion_mutex; + pni_timer_t *proactor_timer; + pn_list_t *timers_heap; + uint64_t timerfd_deadline; + bool sched_timeout; +} pni_timer_manager_t; + struct pn_proactor_t { pcontext_t context; - ptimer_t timer; + pni_timer_manager_t timer_manager; epoll_extended_t epoll_wake; epoll_extended_t epoll_interrupt; pn_event_batch_t batch; pcontext_t *contexts; /* track in-use contexts for PN_PROACTOR_INACTIVE and disconnect */ + pni_timer_t *timer; size_t disconnects_pending; /* unfinished proactor disconnects*/ // need_xxx flags indicate we should generate PN_PROACTOR_XXX on the next update_batch() bool need_interrupt; @@ -151,7 +155,6 @@ struct pn_proactor_t { bool need_timeout; bool timeout_set; /* timeout has been set by user and not yet cancelled or generated event */ bool timeout_processed; /* timeout event dispatched in the most recent event batch */ - bool timer_armed; /* timer is armed in epoll */ int context_count; // wake subsystem @@ -167,7 +170,6 @@ struct pn_proactor_t { pmutex overflow_mutex; // Sched vars specific to proactor context. - bool sched_timeout; bool sched_interrupt; // Global scheduling/poller vars. @@ -220,13 +222,12 @@ typedef struct psocket_t { typedef struct pconnection_t { psocket_t psocket; pcontext_t context; - ptimer_t timer; // TODO: review one timerfd per connection + pni_timer_t *timer; const char *host, *port; uint32_t new_events; int wake_count; // TODO: protected by context.mutex so should be moved in there (also really bool) bool server;/* accept, not connect */ bool tick_pending; - bool timer_armed; bool queued_disconnect; /* deferred from pn_proactor_disconnect() */ pn_condition_t *disconnect_condition; // Following values only changed by (sole) working context: @@ -250,7 +251,7 @@ typedef struct pconnection_t { struct addrinfo *ai; /* Current connect address */ pmutex rearm_mutex;/* protects pconnection_rearm from out of order a