From f1e77f2246726e5e0303eef79f15cd44c4c4a383 Mon Sep 17 00:00:00 2001 From: Bjorn Topel Date: Wed, 30 Jan 2013 16:46:45 +0100 Subject: [PATCH] Removed heap allocation for in zmq_poll for small item sets Until now, zmq_poll always allocates the poll items on the heap. Now, small item sets, up to ZMQ_POLLITEMS_DFLT, are stack allocated and only larger sets are allocated on the heap. --- include/zmq.h | 2 ++ src/zmq.cpp | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/zmq.h b/include/zmq.h index ce00567d..070b43a8 100644 --- a/include/zmq.h +++ b/include/zmq.h @@ -381,6 +381,8 @@ typedef struct short revents; } zmq_pollitem_t; +#define ZMQ_POLLITEMS_DFLT 16 + ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout); /* Built-in message proxy (3-way) */ diff --git a/src/zmq.cpp b/src/zmq.cpp index 52698b1c..7d6fe1ed 100644 --- a/src/zmq.cpp +++ b/src/zmq.cpp @@ -647,9 +647,13 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) zmq::clock_t clock; uint64_t now = 0; uint64_t end = 0; + pollfd spollfds[ZMQ_POLLITEMS_DFLT]; + pollfd *pollfds = spollfds; - pollfd *pollfds = (pollfd*) malloc (nitems_ * sizeof (pollfd)); - alloc_assert (pollfds); + if (nitems_ > ZMQ_POLLITEMS_DFLT) { + pollfds = (pollfd*) malloc (nitems_ * sizeof (pollfd)); + alloc_assert (pollfds); + } // Build pollset for poll () system call. for (int i = 0; i != nitems_; i++) { @@ -660,7 +664,8 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) size_t zmq_fd_size = sizeof (zmq::fd_t); if (zmq_getsockopt (items_ [i].socket, ZMQ_FD, &pollfds [i].fd, &zmq_fd_size) == -1) { - free (pollfds); + if (pollfds != spollfds) + free (pollfds); return -1; } pollfds [i].events = items_ [i].events ? POLLIN : 0; @@ -693,7 +698,8 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) while (true) { int rc = poll (pollfds, nitems_, timeout); if (rc == -1 && errno == EINTR) { - free (pollfds); + if (pollfds != spollfds) + free (pollfds); return -1; } errno_assert (rc >= 0); @@ -711,7 +717,8 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) uint32_t zmq_events; if (zmq_getsockopt (items_ [i].socket, ZMQ_EVENTS, &zmq_events, &zmq_events_size) == -1) { - free (pollfds); + if (pollfds != spollfds) + free (pollfds); return -1; } if ((items_ [i].events & ZMQ_POLLOUT) && @@ -771,7 +778,8 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) break; } - free (pollfds); + if (pollfds != spollfds) + free (pollfds); return nevents; #elif defined ZMQ_POLL_BASED_ON_SELECT