Skip to content

Commit

Permalink
Support so_busy_poll (zeromq#4188)
Browse files Browse the repository at this point in the history
* Support so_busy_poll.
  • Loading branch information
imkcy9 authored May 14, 2021
1 parent ceb5fa3 commit 04c3798
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 1 deletion.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ else()
check_cxx_symbol_exists(if_nametoindex net/if.h HAVE_IF_NAMETOINDEX)
check_cxx_symbol_exists(SO_PEERCRED sys/socket.h ZMQ_HAVE_SO_PEERCRED)
check_cxx_symbol_exists(LOCAL_PEERCRED sys/socket.h ZMQ_HAVE_LOCAL_PEERCRED)
check_cxx_symbol_exists(SO_BUSY_POLL sys/socket.h ZMQ_HAVE_BUSY_POLL)
endif()

if(NOT MINGW)
Expand Down
1 change: 1 addition & 0 deletions builds/cmake/platform.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#cmakedefine ZMQ_HAVE_SO_PEERCRED
#cmakedefine ZMQ_HAVE_LOCAL_PEERCRED
#cmakedefine ZMQ_HAVE_BUSY_POLL

#cmakedefine ZMQ_HAVE_O_CLOEXEC

Expand Down
15 changes: 15 additions & 0 deletions doc/zmq_setsockopt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,21 @@ Default value:: not set
Applicable socket types:: all, when using TCP or UDP transports.


ZMQ_BUSY_POLL: This removes delays caused by the interrupt and the resultant context switch.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Busy polling helps reduce latency in the network receive path by allowing socket layer code
to poll the receive queue of a network device, and disabling network interrupts. This removes
delays caused by the interrupt and the resultant context switch. However, it also increases
CPU utilization. Busy polling also prevents the CPU from sleeping, which can incur additional
power consumption.

[horizontal]
Option value type:: int
Option value unit:: 0,1
Default value:: 0
Applicable socket types:: all


ZMQ_CONNECT_RID: Assign the next outbound connection id
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This option name is now deprecated. Use ZMQ_CONNECT_ROUTING_ID instead.
Expand Down
1 change: 1 addition & 0 deletions include/zmq.h
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,7 @@ ZMQ_EXPORT void zmq_threadclose (void *thread_);
#define ZMQ_HELLO_MSG 110
#define ZMQ_DISCONNECT_MSG 111
#define ZMQ_PRIORITY 112
#define ZMQ_BUSY_POLL 113

/* DRAFT ZMQ_RECONNECT_STOP options */
#define ZMQ_RECONNECT_STOP_CONN_REFUSED 0x1
Expand Down
15 changes: 14 additions & 1 deletion src/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ zmq::options_t::options_t () :
hello_msg (),
can_send_hello_msg (false),
disconnect_msg (),
can_recv_disconnect_msg (false)
can_recv_disconnect_msg (false),
busy_poll (0)
{
memset (curve_public_key, 0, CURVE_KEYSIZE);
memset (curve_secret_key, 0, CURVE_KEYSIZE);
Expand Down Expand Up @@ -802,6 +803,12 @@ int zmq::options_t::setsockopt (int option_,
}
break;

case ZMQ_BUSY_POLL:
if (is_int) {
busy_poll = value;
return 0;
}
break;
#ifdef ZMQ_HAVE_WSS
case ZMQ_WSS_KEY_PEM:
// TODO: check if valid certificate
Expand Down Expand Up @@ -1285,6 +1292,12 @@ int zmq::options_t::getsockopt (int option_,
return 0;
}
break;

case ZMQ_BUSY_POLL:
if (is_int) {
*value = busy_poll;
}
break;
#endif


Expand Down
3 changes: 3 additions & 0 deletions src/options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ struct options_t
// Disconnect msg
std::vector<unsigned char> disconnect_msg;
bool can_recv_disconnect_msg;

// This option removes several delays caused by scheduling, interrupts and context switching.
int busy_poll;
};

inline bool get_effective_conflate_option (const options_t &options)
Expand Down
18 changes: 18 additions & 0 deletions src/tcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,21 @@ void zmq::tcp_tune_loopback_fast_path (const fd_t socket_)
#endif
}

void zmq::tune_tcp_busy_poll (fd_t socket_, int busy_poll_)
{
#if defined(ZMQ_HAVE_BUSY_POLL)
if (busy_poll_ > 0) {
const int rc =
setsockopt (socket_, SOL_SOCKET, SO_BUSY_POLL,
reinterpret_cast<char *> (&busy_poll_), sizeof (int));
assert_success_or_recoverable (socket_, rc);
}
#else
LIBZMQ_UNUSED (socket_);
LIBZMQ_UNUSED (busy_poll_);
#endif
}

zmq::fd_t zmq::tcp_open_socket (const char *address_,
const zmq::options_t &options_,
bool local_,
Expand Down Expand Up @@ -398,6 +413,9 @@ zmq::fd_t zmq::tcp_open_socket (const char *address_,
if (options_.rcvbuf >= 0)
set_tcp_receive_buffer (s, options_.rcvbuf);

// This option removes several delays caused by scheduling, interrupts and context switching.
if (options_.busy_poll)
tune_tcp_busy_poll (s, options_.busy_poll);
return s;

setsockopt_error:
Expand Down
2 changes: 2 additions & 0 deletions src/tcp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ int tcp_read (fd_t s_, void *data_, size_t size_);

void tcp_tune_loopback_fast_path (fd_t socket_);

void tune_tcp_busy_poll (fd_t socket_, int busy_poll_);

// Resolves the given address_ string, opens a socket and sets socket options
// according to the passed options_. On success, returns the socket
// descriptor and assigns the resolved address to out_tcp_addr_. In case of
Expand Down
1 change: 1 addition & 0 deletions src/zmq_draft.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#define ZMQ_HELLO_MSG 110
#define ZMQ_DISCONNECT_MSG 111
#define ZMQ_PRIORITY 112
#define ZMQ_BUSY_POLL 113

/* DRAFT ZMQ_RECONNECT_STOP options */
#define ZMQ_RECONNECT_STOP_CONN_REFUSED 0x1
Expand Down
3 changes: 3 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ if(ENABLE_DRAFTS)
test_hello_msg
test_disconnect_msg
)
if(ZMQ_HAVE_BUSY_POLL)
list(APPEND tests test_busy_poll)
endif()
endif()

if(ZMQ_HAVE_WS)
Expand Down
58 changes: 58 additions & 0 deletions tests/test_busy_poll.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
Copyright (c) 2007-2021 Contributors as noted in the AUTHORS file
This file is part of libzmq, the ZeroMQ core engine in C++.
libzmq is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
As a special exception, the Contributors give you permission to link
this library with independent modules to produce an executable,
regardless of the license terms of these independent modules, and to
copy and distribute the resulting executable under terms of your choice,
provided that you also meet, for each linked independent module, the
terms and conditions of the license of that module. An independent
module is a module which is not derived from or based on this library.
If you modify this library, you must extend this exception to your
version of the library.
libzmq is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "testutil.hpp"
#include "testutil_unity.hpp"

SETUP_TEARDOWN_TESTCONTEXT

void test_busy_poll ()
{
// Create a socket
void *socket = test_context_socket (ZMQ_DEALER);

// set socket ZMQ_BUSY_POLL options
int busy_poll = 1;
TEST_ASSERT_SUCCESS_ERRNO (
zmq_setsockopt (socket, ZMQ_BUSY_POLL, &busy_poll, sizeof (int)));

// bind socket
TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (socket, "tcp://127.0.0.1:*"));

// Clean up.
test_context_socket_close (socket);
}

int main ()
{
setup_test_environment ();
UNITY_BEGIN ();
RUN_TEST (test_busy_poll);
return UNITY_END ();
}

0 comments on commit 04c3798

Please sign in to comment.