[qpid-proton] branch master updated: PROTON-2291: Reduce size of epoll proactor connections - Remove unnecessary proactor back pointer from psocket

2020-11-08 Thread astitcher
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

2020-11-08 Thread cliffjansen
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