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.
This commit is contained in:
Bjorn Topel 2013-01-30 16:46:45 +01:00
parent 470d06bb9e
commit f1e77f2246
2 changed files with 16 additions and 6 deletions

View File

@ -381,6 +381,8 @@ typedef struct
short revents; short revents;
} zmq_pollitem_t; } zmq_pollitem_t;
#define ZMQ_POLLITEMS_DFLT 16
ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout); ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout);
/* Built-in message proxy (3-way) */ /* Built-in message proxy (3-way) */

View File

@ -647,9 +647,13 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
zmq::clock_t clock; zmq::clock_t clock;
uint64_t now = 0; uint64_t now = 0;
uint64_t end = 0; uint64_t end = 0;
pollfd spollfds[ZMQ_POLLITEMS_DFLT];
pollfd *pollfds = spollfds;
pollfd *pollfds = (pollfd*) malloc (nitems_ * sizeof (pollfd)); if (nitems_ > ZMQ_POLLITEMS_DFLT) {
alloc_assert (pollfds); pollfds = (pollfd*) malloc (nitems_ * sizeof (pollfd));
alloc_assert (pollfds);
}
// Build pollset for poll () system call. // Build pollset for poll () system call.
for (int i = 0; i != nitems_; i++) { 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); size_t zmq_fd_size = sizeof (zmq::fd_t);
if (zmq_getsockopt (items_ [i].socket, ZMQ_FD, &pollfds [i].fd, if (zmq_getsockopt (items_ [i].socket, ZMQ_FD, &pollfds [i].fd,
&zmq_fd_size) == -1) { &zmq_fd_size) == -1) {
free (pollfds); if (pollfds != spollfds)
free (pollfds);
return -1; return -1;
} }
pollfds [i].events = items_ [i].events ? POLLIN : 0; 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) { while (true) {
int rc = poll (pollfds, nitems_, timeout); int rc = poll (pollfds, nitems_, timeout);
if (rc == -1 && errno == EINTR) { if (rc == -1 && errno == EINTR) {
free (pollfds); if (pollfds != spollfds)
free (pollfds);
return -1; return -1;
} }
errno_assert (rc >= 0); errno_assert (rc >= 0);
@ -711,7 +717,8 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
uint32_t zmq_events; uint32_t zmq_events;
if (zmq_getsockopt (items_ [i].socket, ZMQ_EVENTS, &zmq_events, if (zmq_getsockopt (items_ [i].socket, ZMQ_EVENTS, &zmq_events,
&zmq_events_size) == -1) { &zmq_events_size) == -1) {
free (pollfds); if (pollfds != spollfds)
free (pollfds);
return -1; return -1;
} }
if ((items_ [i].events & ZMQ_POLLOUT) && if ((items_ [i].events & ZMQ_POLLOUT) &&
@ -771,7 +778,8 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
break; break;
} }
free (pollfds); if (pollfds != spollfds)
free (pollfds);
return nevents; return nevents;
#elif defined ZMQ_POLL_BASED_ON_SELECT #elif defined ZMQ_POLL_BASED_ON_SELECT