ros_comm
ros_comm copied to clipboard
High CPU-load in Debug mode
If ros_comm has been build in Debug-mode (which is catkins default), and one starts roscore, two rosout-process are launch, which taking up about 80% to 160% cpu load. The reason for this is a busy loop in the spinner. The wait_for
calls in CallbackQueue::callAvailable
are not working properly. The reason for that seems to be, that in callback_queue.cpp
BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
is define, and anywhere else it is not. Therefore there are multiple definitions of boost::condition_variable::wait_for
in different translation units, which are not identical. This violation of the one-definition-rule results in the behavior described above.
If one adds add_definitions(-DBOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC)
to the CMakeLists.txt of roscpp and rosout, this problem does not occur.
This problem does not occur in the release, because in Release-mode `ẁait_for`` is inlined and therefore the ODR-violation is not a problem. But If one wants use ros_comm from source this is a problem.
This issue has will occur in every noBOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
de, where boost::condition_variable
is used.
In #1608 this problem has been described before. #1651 is a step in the right direction, but is not sufficient, because BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
needs to be defined in every translation unit, which uses boost::condition_variable
and is linked (statically or dynamically) to roscpp.
One solution would be to extend #1651 and use the internal version of boost::condition_variable
unconditionally, even if the system has Boost 1.61 or higher, and replace all checks for BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
by BOOST_THREAD_HAS_MONO_CLOCK
as if it would be always defined if a monotonic clock source is available.
Or, if possible, copy the Boost 1.67+ implementation of boost::condition_variable
for Boost versions <1.67, which uses the monotonic clock internally and remove BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
completely.
Both alternatives would break the ABI if I am not mistaken, unless the internal memory layout of boost::condition_variable
did not change across all intermediate versions.
This issue should have been fixed by #1878 and #1932 (for melodic-devel
) and #2011 (backport to kinetic-devel
).
For Noetic the custom internal implementation of boost::condition_variable
and the invalid definition of BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
in roscpp/CMakeLists.txt
has been removed completely in https://github.com/ros/ros_comm/pull/1903, because since Boost 1.67 condition variables use the monotonic clock internally by default.