orocos-toolchain / rtt

Orocos Real-Time Toolkit
http://www.orocos.org
Other
72 stars 79 forks source link

Drop usage of Boost Thread for the macosx target and remove ORO_OS_USE_BOOST_THREAD #310

Open meyerj opened 5 years ago

meyerj commented 5 years ago

Addresses https://github.com/orocos-toolchain/rtt/pull/53#issuecomment-370416520:

This patch and also the original version that defines BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG in public headers is invalid.

BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG is a compile-time option of Boost, which should not be defined in a header file. You might get away with defining it in a cpp file and only use Boost header-only functions. But other libraries like Boost.Thread or string formatting in Boost.DateTime are typically pre-compiled and the differences of the internal representation of boost::posix_time::ptime caused by defining BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG might cause run-time errors or unexpected behavior if the user mixes RTT code with calls into one of those Boost libraries.

See http://www.boost.org/doc/libs/1_66_0/more/getting_started/unix-variants.html#header-only-libraries for an overview of which Boost libraries are header-only.

Boost.Thread was used to implement mutexes and condition variables for the macOS target (macosx). The main reason for this was that Apple's implementation of pthread_mutex_t does not have pthread_mutex_timedlock. Workaround: Pair the mutex with a condition variable that is signaled whenever the mutex is unlocked. This is also how boost::timed_mutex is implemented for the case BOOST_THREAD_USES_PTHREAD_TIMEDLOCK is not defined (cf. https://github.com/boostorg/thread/blob/boost-1.62.0/include/boost/thread/pthread/mutex.hpp#L181).

TLSF still uses pthread_mutex_t directly for efficiency.

There was also a bug in TLSF 2.4.6 that was fixed in https://github.com/orocos-toolchain/rtt/commit/3ffcc5ee4accea71209d4d59169e23fd9b00c2fe: The calculation of the maximum size of the area in init_memory_pool() was wrong for certain combinations of mem_size_pool and sizeof(tlsf_t), where

ROUNDUP_SIZE(sizeof(tlsf_t)) + ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t)) > mem_pool_size

. This caused an invalid write after the pool in process_area().

Example:

mem_pool_size = 15000;
sizeof(tlsf_t) = 6392;
BLOCK_ALIGN = 16

==> ROUNDUP_SIZE(sizeof(tlsf_t)) = 6400
    ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t)) = 8608
    ROUNDUP_SIZE(sizeof(tlsf_t))) + ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t)) = 15008

The fix is to add another ROUNDUP_SIZE() macro call in the second summand:

ROUNDUP_SIZE(sizeof(tlsf_t))) + ROUNDDOWN_SIZE(mem_pool_size - ROUNDUP_SIZE(sizeof(tlsf_t))) = 14992