Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use std::condition_variable_any, move configuration to build files #3405

Merged
merged 6 commits into from
Feb 12, 2019

Conversation

sigiesec
Copy link
Member

@sigiesec sigiesec commented Feb 11, 2019

Fixes #3404

  • port ZMQ_USE_CV_IMPL_* configuration to Autotools (@bluca I am somewhat lost wrt that, could you give me some hints?)

…ck<std::mutex>, leading to two mutexes used in condition_variable_t

Solution: use std::condition_variable_any instead
@sigiesec sigiesec changed the title [WiP, do not merge] Use std::condition_variable_any [WiP, do not merge] Use std::condition_variable_any, move configuration to build files Feb 11, 2019
@bluca
Copy link
Member

bluca commented Feb 11, 2019

I can have a look at providing the autoconf one later tonight, but what is the check looking for exactly?

@sigiesec
Copy link
Member Author

sigiesec commented Feb 11, 2019

What I implemented for CMake now are the following defaults:

  1. if C++11 STL's <condition_variable> can be included, use the STL implementation
  2. otherwise, if the Windows API CONDITION_VARIABLE implementation is available, use the Win32API implementation (this case can probably be skipped in Autotools)
  3. otherwise, if pthread is available, use the pthreads implementation
  4. otherwise, use the null-implementation (this still needs to be changed, such that in this case, no condition_variable_t is defined at all; I started working on this as well, but it is more complex)

The user can provide a custom value for ZMQ_USE_CV_IMPL, which overrides the above defaults.

autotools must probably also have a case for vxworks

@sigiesec sigiesec force-pushed the use-std-condition-variable-any branch 2 times, most recently from b05b436 to f25f5a1 Compare February 11, 2019 14:56
@bluca
Copy link
Member

bluca commented Feb 11, 2019

@sigiesec here's a working diff:

--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1189,3 +1189,44 @@ AC_DEFUN([LIBZMQ_CHECK_CACHELINE], [{
        AC_MSG_NOTICE([Using "$zmq_cacheline_size" bytes alignment for lock-free data structures])
        AC_DEFINE_UNQUOTED(ZMQ_CACHELINE_SIZE, $zmq_cacheline_size, [Using "$zmq_cacheline_size" bytes alignment for lock-free data structures])
 }])
+
+dnl ################################################################################
+dnl # LIBZMQ_CHECK_CV_IMPL([action-if-found], [action-if-not-found])               #
+dnl # Choose condition variable implementation                                     #
+dnl ################################################################################
+
+AC_DEFUN([LIBZMQ_CHECK_CV_IMPL], [{
+    # Allow user to override condition variable autodetection
+    AC_ARG_WITH([cv-impl],
+        [AS_HELP_STRING([--with-cv-impl],
+        [choose condition variable implementation manually. Valid values are 'stl11', 'pthread', 'none', or 'auto'. [default=auto]])])
+
+    if test "x$with_cv_impl" == "x"; then
+        cv_impl=auto
+    else
+        cv_impl=$with_cv_impl
+    fi
+    case $host_os in
+      vxworks*)
+        cv_impl="vxworks"
+        AC_DEFINE(ZMQ_USE_CV_IMPL_VXWORKS, 1, [Use vxworks condition variable implementation.])
+      ;;
+    esac
+    if test "$cv_impl" == "auto" || test "$cv_impl" == "stl11"; then
+        AC_LANG_PUSH([C++])
+        AC_CHECK_HEADERS(condition_variable, [stl11="yes"
+            AC_DEFINE(ZMQ_USE_CV_IMPL_STL11, 1, [Use stl11 condition variable implementation.])],
+            [stl11="no"])
+        AC_LANG_POP([C++])
+        if test "$cv_impl" == "stl11" && test "x$stl11" == "xno"; then
+            AC_MSG_ERROR([--with-cv-impl set to stl11 but cannot find condition_variable])
+        fi
+    fi
+    if test "$cv_impl" == "pthread" || test "x$stl11" == "xno"; then
+        AC_DEFINE(ZMQ_USE_CV_IMPL_PTHREADS, 1, [Use pthread condition variable implementation.])
+    fi
+    if test "$cv_impl" == "none"; then
+        AC_DEFINE(ZMQ_USE_CV_IMPL_NONE, 1, [Use no condition variable implementation.])
+    fi
+       AC_MSG_NOTICE([Using "$cv_impl" condition variable implementation.])
+}])
--- a/configure.ac
+++ b/configure.ac
@@ -381,6 +381,9 @@ LIBZMQ_CHECK_POLLER
 # Check cacheline size, set appropriate macro in src/platform.hpp
 LIBZMQ_CHECK_CACHELINE
 
+# Check condition variable implementation, set appropriate macro in src/platform.hpp
+LIBZMQ_CHECK_CV_IMPL
+
 # Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS(\

@bluca
Copy link
Member

bluca commented Feb 11, 2019

that said, I'm not a huge fan of having such a granular and low-level option - if anything, it should force C98 compat for everything or for nothing - which already exists as --enable-force-CXX98-compat

@sigiesec
Copy link
Member Author

First of all, thanks a lot for the patch!

I'm not a huge fan of having such a granular and low-level option

Hm, why? I think the options in general deserve some better naming/structuring, but when this were done, it doesn't hurt to make all things configurable, where the choice is not absolutely clear (because only 1 of n can work at all, or is clearly better on all supporting platforms).

if anything, it should force C98 compat for everything or for nothing - which already exists as --enable-force-CXX98-compat

I don't quite understand this in particular. The choice between implementations does not need to have something to do with compatibility. It depends on the platform which implementation is better (esp. performance-wise). And at least on MinGW, you actually have the choice between three implementations, namely pthreads, win32api and stl11.

Solution: calculate from CMAKE_SYSTEM_VERSION

Problem: CMAKE_SYSTEM_VERSION might be newer than Windows SDK Version

Solution: limit _WIN32_WINNT value to Visual Studio default Windows SDK version
…g and not configurable

Solution: move configuration to build definition
…newer due to duplicate definition of htonll

Solution: use custom implementation only on older Windows versions
Solution: change into regular control flow condition
@sigiesec sigiesec force-pushed the use-std-condition-variable-any branch from bf3ec80 to 7fbd977 Compare February 12, 2019 08:47
@sigiesec sigiesec changed the title [WiP, do not merge] Use std::condition_variable_any, move configuration to build files Use std::condition_variable_any, move configuration to build files Feb 12, 2019
@bluca
Copy link
Member

bluca commented Feb 12, 2019

To put it in another way: is there any reason someone would want to pick the C11 implementation of foo, but the C98 implementation of bar? As far as I can see, either one wants max compatibility or the modern implementations, which are usually better

@sigiesec
Copy link
Member Author

I think the "usually" restriction is the point. I am not sure about std::condition_variable, but std::mutex on VS2015, e.g., is supported but significantly slower than using CRITICAL_SECTION

@bluca
Copy link
Member

bluca commented Feb 12, 2019

ok, fair enough - the options should be cross-checked with the force-cxx98 flag as well, to avoid inconsistent configurations

@sigiesec
Copy link
Member Author

Should anything be added in either the autotools or cmake code before merging?

@bluca bluca merged commit 6937447 into zeromq:master Feb 12, 2019
@bluca
Copy link
Member

bluca commented Feb 12, 2019

No, looks good to me, thanks

@sigiesec sigiesec deleted the use-std-condition-variable-any branch March 1, 2019 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants