From ec6822a477b89ac77afc90425bf36c4829dbef3d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Sep 2009 11:30:49 +0200 Subject: win port for c and cpp perf tests --- c/zmq.h | 8 +- cpp/zmq.hpp | 7 ++ msvc/c_local_lat/c_local_lat.vcproj | 176 ++++++++++++++++++++++++++++++ msvc/c_local_thr/c_local_thr.vcproj | 176 ++++++++++++++++++++++++++++++ msvc/c_remote_lat/c_remote_lat.vcproj | 176 ++++++++++++++++++++++++++++++ msvc/c_remote_thr/c_remote_thr.vcproj | 176 ++++++++++++++++++++++++++++++ msvc/cpp_local_lat/cpp_local_lat.vcproj | 176 ++++++++++++++++++++++++++++++ msvc/cpp_local_thr/cpp_local_thr.vcproj | 176 ++++++++++++++++++++++++++++++ msvc/cpp_remote_lat/cpp_remote_lat.vcproj | 176 ++++++++++++++++++++++++++++++ msvc/cpp_remote_thr/cpp_remote_thr.vcproj | 176 ++++++++++++++++++++++++++++++ msvc/libzmq/libzmq.vcproj | 10 +- msvc/msvc.sln | 72 ++++++++++++ perf/c/local_lat.c | 3 +- perf/c/local_thr.c | 24 ++-- perf/c/remote_lat.c | 19 +--- perf/c/remote_thr.c | 3 +- perf/cpp/local_lat.cpp | 3 +- perf/cpp/local_thr.cpp | 20 +--- perf/cpp/remote_lat.cpp | 16 +-- perf/cpp/remote_thr.cpp | 3 +- src/fd_signaler.cpp | 2 +- src/tcp_connecter.cpp | 18 ++- src/tcp_listener.cpp | 89 ++++++++++++++- src/tcp_socket.cpp | 5 + src/zmq.cpp | 67 +++++++++++- 25 files changed, 1702 insertions(+), 75 deletions(-) create mode 100644 msvc/c_local_lat/c_local_lat.vcproj create mode 100644 msvc/c_local_thr/c_local_thr.vcproj create mode 100644 msvc/c_remote_lat/c_remote_lat.vcproj create mode 100644 msvc/c_remote_thr/c_remote_thr.vcproj create mode 100644 msvc/cpp_local_lat/cpp_local_lat.vcproj create mode 100644 msvc/cpp_local_thr/cpp_local_thr.vcproj create mode 100644 msvc/cpp_remote_lat/cpp_remote_lat.vcproj create mode 100644 msvc/cpp_remote_thr/cpp_remote_thr.vcproj diff --git a/c/zmq.h b/c/zmq.h index a8394ed..cc165d1 100644 --- a/c/zmq.h +++ b/c/zmq.h @@ -26,7 +26,7 @@ extern "C" { #include -#if defined MSC_VER && defined ZMQ_BUILDING_LIBZMQ +#if defined ZMQ_BUILDING_LIBZMQ_WITH_MSVC #define ZMQ_EXPORT __declspec(dllexport) #else #define ZMQ_EXPORT @@ -199,6 +199,12 @@ ZMQ_EXPORT int zmq_flush (void *s); // ENOTSUP - function isn't supported by particular socket type. ZMQ_EXPORT int zmq_recv (void *s, struct zmq_msg_t *msg, int flags); +// Helper functions used by perf tests so that they don't have to care +// about minutiae of time-related functions on different OS platforms. +ZMQ_EXPORT void *zmq_stopwatch_start (); +ZMQ_EXPORT unsigned long zmq_stopwatch_stop (void *watch_); +ZMQ_EXPORT void zmq_sleep (int seconds_); + #ifdef __cplusplus } #endif diff --git a/cpp/zmq.hpp b/cpp/zmq.hpp index ffdea7b..471d1d8 100644 --- a/cpp/zmq.hpp +++ b/cpp/zmq.hpp @@ -48,7 +48,14 @@ namespace zmq virtual const char *what () const throw () { +#if defined _MSC_VER +#pragma warning (push) +#pragma warning (disable:4996) +#endif return strerror (errnum); +#if defined _MSC_VER +#pragma warning (pop) +#endif } private: diff --git a/msvc/c_local_lat/c_local_lat.vcproj b/msvc/c_local_lat/c_local_lat.vcproj new file mode 100644 index 0000000..22c558c --- /dev/null +++ b/msvc/c_local_lat/c_local_lat.vcproj @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/c_local_thr/c_local_thr.vcproj b/msvc/c_local_thr/c_local_thr.vcproj new file mode 100644 index 0000000..f80f075 --- /dev/null +++ b/msvc/c_local_thr/c_local_thr.vcproj @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/c_remote_lat/c_remote_lat.vcproj b/msvc/c_remote_lat/c_remote_lat.vcproj new file mode 100644 index 0000000..3e482af --- /dev/null +++ b/msvc/c_remote_lat/c_remote_lat.vcproj @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/c_remote_thr/c_remote_thr.vcproj b/msvc/c_remote_thr/c_remote_thr.vcproj new file mode 100644 index 0000000..4cecc53 --- /dev/null +++ b/msvc/c_remote_thr/c_remote_thr.vcproj @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/cpp_local_lat/cpp_local_lat.vcproj b/msvc/cpp_local_lat/cpp_local_lat.vcproj new file mode 100644 index 0000000..a16dfb9 --- /dev/null +++ b/msvc/cpp_local_lat/cpp_local_lat.vcproj @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/cpp_local_thr/cpp_local_thr.vcproj b/msvc/cpp_local_thr/cpp_local_thr.vcproj new file mode 100644 index 0000000..33f74cc --- /dev/null +++ b/msvc/cpp_local_thr/cpp_local_thr.vcproj @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/cpp_remote_lat/cpp_remote_lat.vcproj b/msvc/cpp_remote_lat/cpp_remote_lat.vcproj new file mode 100644 index 0000000..ba1f943 --- /dev/null +++ b/msvc/cpp_remote_lat/cpp_remote_lat.vcproj @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/cpp_remote_thr/cpp_remote_thr.vcproj b/msvc/cpp_remote_thr/cpp_remote_thr.vcproj new file mode 100644 index 0000000..6448151 --- /dev/null +++ b/msvc/cpp_remote_thr/cpp_remote_thr.vcproj @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/libzmq/libzmq.vcproj b/msvc/libzmq/libzmq.vcproj index e1d69d7..2a33dbb 100644 --- a/msvc/libzmq/libzmq.vcproj +++ b/msvc/libzmq/libzmq.vcproj @@ -19,7 +19,7 @@ Name="Debug|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="1" + ConfigurationType="2" CharacterSet="2" > @@ -87,7 +90,7 @@ Name="Release|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="1" + ConfigurationType="2" CharacterSet="2" WholeProgramOptimization="1" > @@ -109,6 +112,7 @@ /> #include #include -#include #include int main (int argc, char *argv []) @@ -66,7 +65,7 @@ int main (int argc, char *argv []) rc = zmq_msg_close (&msg); assert (rc == 0); - sleep (1); + zmq_sleep (1); rc = zmq_close (s); assert (rc == 0); diff --git a/perf/c/local_thr.c b/perf/c/local_thr.c index 71ed21c..83ebee1 100644 --- a/perf/c/local_thr.c +++ b/perf/c/local_thr.c @@ -21,8 +21,6 @@ #include #include #include -#include -#include int main (int argc, char *argv []) { @@ -34,10 +32,9 @@ int main (int argc, char *argv []) int rc; int i; struct zmq_msg_t msg; - struct timeval start; - struct timeval end; - uint64_t elapsed; - uint64_t throughput; + void *watch; + unsigned long elapsed; + unsigned long throughput; double megabits; if (argc != 4) { @@ -64,8 +61,7 @@ int main (int argc, char *argv []) assert (rc == 0); assert (zmq_msg_size (&msg) == message_size); - rc = gettimeofday (&start, NULL); - assert (rc == 0); + watch = zmq_stopwatch_start (); for (i = 0; i != message_count - 1; i++) { rc = zmq_recv (s, &msg, 0); @@ -73,17 +69,11 @@ int main (int argc, char *argv []) assert (zmq_msg_size (&msg) == message_size); } - rc = gettimeofday (&end, NULL); - assert (rc == 0); - - end.tv_sec -= start.tv_sec; - start.tv_sec = 0; - - elapsed = ((uint64_t) end.tv_sec * 1000000 + end.tv_usec) - - ((uint64_t) start.tv_sec * 1000000 + start.tv_usec); + elapsed = zmq_stopwatch_stop (watch); if (elapsed == 0) elapsed = 1; - throughput = (uint64_t) message_count * 1000000 / elapsed; + + throughput = (double) message_count / (double) elapsed * 1000000; megabits = (double) (throughput * message_size * 8) / 1000000; printf ("message size: %d [B]\n", (int) message_size); diff --git a/perf/c/remote_lat.c b/perf/c/remote_lat.c index 6da1c42..23695b4 100644 --- a/perf/c/remote_lat.c +++ b/perf/c/remote_lat.c @@ -21,7 +21,6 @@ #include #include #include -#include int main (int argc, char *argv []) { @@ -33,9 +32,8 @@ int main (int argc, char *argv []) int rc; int i; struct zmq_msg_t msg; - struct timeval start; - struct timeval end; - double elapsed; + void *watch; + unsigned long elapsed; double latency; if (argc != 4) { @@ -56,8 +54,7 @@ int main (int argc, char *argv []) rc = zmq_connect (s, connect_to); assert (rc == 0); - rc = gettimeofday (&start, NULL); - assert (rc == 0); + watch = zmq_stopwatch_start (); rc = zmq_msg_init_size (&msg, message_size); assert (rc == 0); @@ -73,15 +70,9 @@ int main (int argc, char *argv []) rc = zmq_msg_close (&msg); assert (rc == 0); - rc = gettimeofday (&end, NULL); - assert (rc == 0); - - end.tv_sec -= start.tv_sec; - start.tv_sec = 0; + elapsed = zmq_stopwatch_stop (watch); - elapsed = (end.tv_sec * 1000000 + end.tv_usec) - - (start.tv_sec * 1000000 + start.tv_usec); - latency = elapsed / (roundtrip_count * 2); + latency = (double) elapsed / (roundtrip_count * 2); printf ("message size: %d [B]\n", (int) message_size); printf ("roundtrip count: %d\n", (int) roundtrip_count); diff --git a/perf/c/remote_thr.c b/perf/c/remote_thr.c index 9606d00..3069640 100644 --- a/perf/c/remote_thr.c +++ b/perf/c/remote_thr.c @@ -20,7 +20,6 @@ #include #include #include -#include #include int main (int argc, char *argv []) @@ -61,7 +60,7 @@ int main (int argc, char *argv []) assert (rc == 0); } - sleep (10); + zmq_sleep (10); rc = zmq_close (s); assert (rc == 0); diff --git a/perf/cpp/local_lat.cpp b/perf/cpp/local_lat.cpp index 343ca74..d8fee2e 100644 --- a/perf/cpp/local_lat.cpp +++ b/perf/cpp/local_lat.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -47,7 +46,7 @@ int main (int argc, char *argv []) s.send (msg); } - sleep (1); + zmq_sleep (1); return 0; } diff --git a/perf/cpp/local_thr.cpp b/perf/cpp/local_thr.cpp index 31fcd16..7d40904 100644 --- a/perf/cpp/local_thr.cpp +++ b/perf/cpp/local_thr.cpp @@ -22,8 +22,6 @@ #include #include #include -#include -#include int main (int argc, char *argv []) { @@ -45,27 +43,17 @@ int main (int argc, char *argv []) s.recv (&msg); assert (msg.size () == message_size); - timeval start; - int rc = gettimeofday (&start, NULL); - assert (rc == 0); + void *watch = zmq_stopwatch_start (); for (int i = 1; i != message_count; i++) { s.recv (&msg); assert (msg.size () == message_size); } - timeval end; - rc = gettimeofday (&end, NULL); - assert (rc == 0); + unsigned long elapsed = zmq_stopwatch_stop (watch); - end.tv_sec -= start.tv_sec; - start.tv_sec = 0; - - uint64_t elapsed = ((uint64_t) end.tv_sec * 1000000 + end.tv_usec) - - ((uint64_t) start.tv_sec * 1000000 + start.tv_usec); - if (elapsed == 0) - elapsed = 1; - uint64_t throughput = (uint64_t) message_count * 1000000 / elapsed; + unsigned long throughput = (unsigned long) + ((double) message_count / (double) elapsed * 1000000); double megabits = (double) (throughput * message_size * 8) / 1000000; printf ("message size: %d [B]\n", (int) message_size); diff --git a/perf/cpp/remote_lat.cpp b/perf/cpp/remote_lat.cpp index a88d53d..f1d2a17 100644 --- a/perf/cpp/remote_lat.cpp +++ b/perf/cpp/remote_lat.cpp @@ -22,7 +22,6 @@ #include #include #include -#include int main (int argc, char *argv []) { @@ -40,9 +39,7 @@ int main (int argc, char *argv []) zmq::socket_t s (ctx, ZMQ_REQ); s.connect (connect_to); - timeval start; - int rc = gettimeofday (&start, NULL); - assert (rc == 0); + void *watch = zmq_stopwatch_start (); for (int i = 0; i != roundtrip_count; i++) { zmq::message_t msg (message_size); @@ -51,16 +48,9 @@ int main (int argc, char *argv []) assert (msg.size () == message_size); } - timeval end; - rc = gettimeofday (&end, NULL); - assert (rc == 0); + unsigned long elapsed = zmq_stopwatch_stop (watch); - end.tv_sec -= start.tv_sec; - start.tv_sec = 0; - - double elapsed = (end.tv_sec * 1000000 + end.tv_usec) - - (start.tv_sec * 1000000 + start.tv_usec); - double latency = elapsed / (roundtrip_count * 2); + double latency = (double) elapsed / (roundtrip_count * 2); printf ("message size: %d [B]\n", (int) message_size); printf ("roundtrip count: %d\n", (int) roundtrip_count); diff --git a/perf/cpp/remote_thr.cpp b/perf/cpp/remote_thr.cpp index 5474c6a..a4008df 100644 --- a/perf/cpp/remote_thr.cpp +++ b/perf/cpp/remote_thr.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -45,7 +44,7 @@ int main (int argc, char *argv []) s.send (msg); } - sleep (10); + zmq_sleep (10); return 0; } diff --git a/src/fd_signaler.cpp b/src/fd_signaler.cpp index 3f433b8..862b0fd 100644 --- a/src/fd_signaler.cpp +++ b/src/fd_signaler.cpp @@ -151,7 +151,7 @@ zmq::fd_signaler_t::signals_t zmq::fd_signaler_t::check () signals_t signals = 0; for (int pos = 0; pos != nbytes; pos++) { zmq_assert (buffer [pos] < 64); - signals |= (1 << (buffer [pos])); + signals |= (signals_t (1) << (buffer [pos])); } return signals; } diff --git a/src/tcp_connecter.cpp b/src/tcp_connecter.cpp index fa99538..22caafb 100644 --- a/src/tcp_connecter.cpp +++ b/src/tcp_connecter.cpp @@ -98,7 +98,23 @@ zmq::fd_t zmq::tcp_connecter_t::get_fd () return s; } -// connect +zmq::fd_t zmq::tcp_connecter_t::connect () +{ + // Nonblocking connect have finished. Check whether an error occured. + int err = 0; + socklen_t len = sizeof err; + int rc = getsockopt (s, SOL_SOCKET, SO_ERROR, (char*) &err, &len); + zmq_assert (rc == 0); + if (err != 0) { + errno = err; + return retired_fd; + } + + // Return the newly connected socket. + fd_t result = s; + s = retired_fd; + return result; +} #else diff --git a/src/tcp_listener.cpp b/src/tcp_listener.cpp index 22d47ca..9431ccf 100644 --- a/src/tcp_listener.cpp +++ b/src/tcp_listener.cpp @@ -27,7 +27,94 @@ #ifdef ZMQ_HAVE_WINDOWS -#error +zmq::tcp_listener_t::tcp_listener_t () : + s (retired_fd) +{ + memset (&addr, 0, sizeof (addr)); +} + +zmq::tcp_listener_t::~tcp_listener_t () +{ + if (s != retired_fd) + close (); +} + +int zmq::tcp_listener_t::set_address (const char *addr_) +{ + // Convert the interface into sockaddr_in structure. + int rc = resolve_ip_interface (&addr, addr_); + if (rc != 0) + return rc; + + // Create a listening socket. + s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + // TODO: Convert error code to errno. + wsa_assert (s != INVALID_SOCKET); + + // Allow reusing of the address. + int flag = 1; + rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, + (const char*) &flag, sizeof (int)); + wsa_assert (rc != SOCKET_ERROR); + + // Set the non-blocking flag. + flag = 1; + rc = ioctlsocket (s, FIONBIO, (u_long*) &flag); + wsa_assert (rc != SOCKET_ERROR); + + // Bind the socket to the network interface and port. + rc = bind (s, (struct sockaddr*) &addr, sizeof (addr)); + // TODO: Convert error code to errno. + wsa_assert (rc != SOCKET_ERROR); + + // Listen for incomming connections. + rc = listen (s, 1); + // TODO: Convert error code to errno. + wsa_assert (rc != SOCKET_ERROR); + + return 0; +} + +int zmq::tcp_listener_t::close () +{ + zmq_assert (s != retired_fd); + int rc = closesocket (s); + wsa_assert (rc != SOCKET_ERROR); + s = retired_fd; + return 0; +} + +zmq::fd_t zmq::tcp_listener_t::get_fd () +{ + return s; +} + +zmq::fd_t zmq::tcp_listener_t::accept () +{ + zmq_assert (s != retired_fd); + + // Accept one incoming connection. + fd_t sock = ::accept (s, NULL, NULL); + if (sock == INVALID_SOCKET && + (WSAGetLastError () == WSAEWOULDBLOCK || + WSAGetLastError () == WSAECONNRESET)) + return retired_fd; + + zmq_assert (sock != INVALID_SOCKET); + + // Set to non-blocking mode. + unsigned long argp = 1; + int rc = ioctlsocket (sock, FIONBIO, &argp); + wsa_assert (rc != SOCKET_ERROR); + + // Disable Nagle's algorithm. + int flag = 1; + rc = setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, + sizeof (int)); + wsa_assert (rc != SOCKET_ERROR); + + return sock; +} #else diff --git a/src/tcp_socket.cpp b/src/tcp_socket.cpp index 21f60f9..782f0d8 100644 --- a/src/tcp_socket.cpp +++ b/src/tcp_socket.cpp @@ -50,6 +50,11 @@ int zmq::tcp_socket_t::close () return 0; } +zmq::fd_t zmq::tcp_socket_t::get_fd () +{ + return s; +} + int zmq::tcp_socket_t::write (const void *data, int size) { int nbytes = send (s, (char*) data, size, 0); diff --git a/src/zmq.cpp b/src/zmq.cpp index ad4839f..63a7b4b 100644 --- a/src/zmq.cpp +++ b/src/zmq.cpp @@ -27,6 +27,13 @@ #include "err.hpp" #include "dispatcher.hpp" #include "msg_content.hpp" +#include "platform.hpp" +#include "stdint.hpp" + +#if !defined ZMQ_HAVE_WINDOWS +#include +#include +#endif int zmq_msg_init (zmq_msg_t *msg_) { @@ -39,7 +46,7 @@ int zmq_msg_init_size (zmq_msg_t *msg_, size_t size_) { if (size_ <= ZMQ_MAX_VSM_SIZE) { msg_->content = (zmq::msg_content_t*) ZMQ_VSM; - msg_->vsm_size = (uint16_t) size_; + msg_->vsm_size = (uint8_t) size_; } else { msg_->content = @@ -228,3 +235,61 @@ int zmq_recv (void *s_, zmq_msg_t *msg_, int flags_) { return (((zmq::socket_base_t*) s_)->recv (msg_, flags_)); } + +#if defined ZMQ_HAVE_WINDOWS + +static uint64_t now () +{ + // Get the high resolution counter's accuracy. + LARGE_INTEGER ticksPerSecond; + QueryPerformanceFrequency (&ticksPerSecond); + + // What time is it? + LARGE_INTEGER tick; + QueryPerformanceCounter (&tick); + + // Convert the tick number into the number of seconds + // since the system was started. + double ticks_div = (double) (ticksPerSecond.QuadPart / 1000000); + return (uint64_t) (tick.QuadPart / ticks_div); +} + +void zmq_sleep (int seconds_) +{ + Sleep (seconds_ * 1000); +} + +#else + +static uint64_t now () +{ + struct timeval tv; + int rc; + + rc = gettimeofday (&tv, NULL); + assert (rc == 0); + return (tv.tv_sec * (uint64_t) 1000000 + tv.tv_usec); +} + +void zmq_sleep (int seconds_) +{ + sleep (seconds_); +} + +#endif + +void *zmq_stopwatch_start () +{ + uint64_t *watch = (uint64_t*) malloc (sizeof (uint64_t)); + zmq_assert (watch); + *watch = now (); + return (void*) watch; +} + +unsigned long zmq_stopwatch_stop (void *watch_) +{ + uint64_t end = now (); + uint64_t start = *(uint64_t*) watch_; + free (watch_); + return (unsigned long) (end - start); +} \ No newline at end of file -- cgit v1.2.3