Modifying memory pool helps me find a hidden bug

My project has a CUDA memory pool which uses C++‘s std::queue. Allocating from the head of queue:

ptr = q.front();
q.pop(); 

While freeing memory insert it into the tail of queue:

q.push(ptr);  

I changed the implementation from std::queue to std::deque. Both allocating and freeing all occur in the front of queue:

ptr = q.front();
q.pop_front();
......
q.push_front(ptr);

This modification helps me find a hidden bug which is releasing memory early. In origin code, the memory is inserted at the end of queue. So there is a interval between it is reused by other threads and current thread, and the work can still be done correctly as long as it is not reused by others. But after using std::deque, the memory is immediately used by other threads, which disclose the bug.

 

Be wary of “Boost”, not “boost” in CMakeLists.txt

In Cygwin, the following statements in CMakeLists.txt:

......
find_package(boost 1.66 REQUIRED COMPONENTS system)
if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIRS})
    add_executable(play main.cpp)
    target_link_libraries(play ${Boost_LIBRARIES})
endif()
......

causes following errors:

......
CMakeFiles/play.dir/main.cpp.o: In function `boost::system::error_code::error_code()':
/usr/include/boost/system/error_code.hpp:449: undefined reference to `boost::system::system_category()'
/usr/include/boost/system/error_code.hpp:449:(.text$_ZN5boost6system10error_codeC1Ev[_ZN5boost6system10error_codeC1Ev]+0x17): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::system_category()'
CMakeFiles/play.dir/main.cpp.o: In function `boost::system::error_category::std_category::equivalent(int, std::error_condition const&) const':
/usr/include/boost/system/error_code.hpp:676: undefined reference to `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:676:(.text$_ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition[_ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition]+0xa9): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:679: undefined reference to `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:679:(.text$_ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition[_ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition]+0xe4): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::generic_category()'
CMakeFiles/play.dir/main.cpp.o: In function `boost::system::error_category::std_category::equivalent(std::error_code const&, int) const':
/usr/include/boost/system/error_code.hpp:706: undefined reference to `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:706:(.text$_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei[_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei]+0xab): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:709: undefined reference to `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:709:(.text$_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei[_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei]+0xe6): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:721: undefined reference to `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:721:(.text$_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei[_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei]+0x1be): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::generic_category()'
CMakeFiles/play.dir/main.cpp.o: In function `boost::asio::error::get_system_category()':
/usr/include/boost/asio/error.hpp:229: undefined reference to `boost::system::system_category()'
/usr/include/boost/asio/error.hpp:229:(.text$_ZN5boost4asio5error19get_system_categoryEv[_ZN5boost4asio5error19get_system_categoryEv]+0x9): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::system_category()'
collect2: error: ld returned 1 exit status

Change boost to Boost:

find_package(Boost 1.66 REQUIRED COMPONENTS system)
......

All is OK now!

Use boost on OpenBSD

Installing boost on OpenBSD is simple:

$ pkg_add boost

Write a simple test program:

#include <boost/asio.hpp>
#include <iostream>

int main()
{
    boost::system::error_code ec{};
    auto server_addr{boost::asio::ip::make_address("127.0.0.1", ec)};
    if (ec.value())
    {
        std::cerr << "Failed to parse the IP address. Error code = "
                    << ec.value() << ". Message: " << ec.message();
        return ec.value();
    }

    boost::asio::ip::tcp::endpoint ep{server_addr, 3003};
    return 0;
}

Compile it:

$ c++ client.cpp
/tmp/client-238877.o: In function `boost::asio::error::get_system_category()':
client.cpp:(.text._ZN5boost4asio5error19get_system_categoryEv[_ZN5boost4asio5error19get_system_categoryEv]+0x5): undefined reference to `boost::system::system_category()'
/tmp/client-238877.o: In function `boost::system::error_code::error_code()':
client.cpp:(.text._ZN5boost6system10error_codeC2Ev[_ZN5boost6system10error_codeC2Ev]+0x1b): undefined reference to `boost::system::system_category()'
/tmp/client-238877.o: In function `boost::system::error_category::std_category::equivalent(int, std::__1::error_condition const&) const':
client.cpp:(.text._ZNK5boost6system14error_category12std_category10equivalentEiRKNSt3__115error_conditionE[_ZNK5boost6system14error_category12std_category10equivalentEiRKNSt3__115error_conditionE]+0x129): undefined reference to `boost::system::generic_category()'
client.cpp:(.text._ZNK5boost6system14error_category12std_category10equivalentEiRKNSt3__115error_conditionE[_ZNK5boost6system14error_category12std_category10equivalentEiRKNSt3__115error_conditionE]+0x16a): undefined reference to `boost::system::generic_category()'
/tmp/client-238877.o: In function `boost::system::error_category::std_category::equivalent(std::__1::error_code const&, int) const':
client.cpp:(.text._ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi[_ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi]+0x137): undefined reference to `boost::system::generic_category()'
client.cpp:(.text._ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi[_ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi]+0x178): undefined reference to `boost::system::generic_category()'
client.cpp:(.text._ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi[_ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi]+0x2d2): undefined reference to `boost::system::generic_category()'
c++: error: linker command failed with exit code 1 (use -v to see invocation)

Whoops!, it means linker can’t find related library. boost libraries are installed in /usr/local/lib:

$ ls -lt /usr/local/lib/libboost*
-rw-r--r--  1 root  bin  2632774 Jul  2 05:58 /usr/local/lib/libboost_regex-mt.a
-rw-r--r--  1 root  bin  1398613 Jul  2 05:58 /usr/local/lib/libboost_regex-mt.so.8.0
-rw-r--r--  1 root  bin  2632774 Jul  2 05:58 /usr/local/lib/libboost_regex.a
-rw-r--r--  1 root  bin  1398613 Jul  2 05:58 /usr/local/lib/libboost_regex.so.8.0
-rw-r--r--  1 root  bin   994564 Jul  2 05:58 /usr/local/lib/libboost_serialization-mt.a
-rw-r--r--  1 root  bin   484918 Jul  2 05:58 /usr/local/lib/libboost_serialization-mt.so.8.0
-rw-r--r--  1 root  bin   994564 Jul  2 05:58 /usr/local/lib/libboost_serialization.a
-rw-r--r--  1 root  bin   484918 Jul  2 05:58 /usr/local/lib/libboost_serialization.so.8.0
-rw-r--r--  1 root  bin   260322 Jul  2 05:58 /usr/local/lib/libboost_signals-mt.a
-rw-r--r--  1 root  bin   154973 Jul  2 05:58 /usr/local/lib/libboost_signals-mt.so.8.0
-rw-r--r--  1 root  bin   260322 Jul  2 05:58 /usr/local/lib/libboost_signals.a
......

So I should specify boost_system library during compilation:

$ c++ -L/usr/local/lib client.cpp -lboost_system
$

This time it works!

The difference between const&constexpr objects in C++

In C++, const object means once initialized, its value can’t be changed. The initialization can occur in compile-time:

const auto c = 0;

Or in run-time:

#include <cstdlib>
#include <ctime>

auto func()
{
    return std::rand() % 10;
}

int main()
{
    std::srand(std::time(0));
    const auto c = func();

    return 0;
}

For constexpr objects, you can think they are a subset of const objects, and the constexpr object’s value must be determined in compile-time. Change the declaration of c in above code:

constexpr auto c = func();

The code can’t be compiled because the c‘s value couldn’t be generated during compilation phrase.

Why do I recommend learning C++?

This post is just my ramblings about why I recommend you learn C++ even in 2018:

(1) C++ is a system programming language, and the program implemented in C++ is compiled into machine instructions. IMHO, every genuine software engineer should be acquainted with Operating System, hardware architecture, etc, and learning C++ can give you the opportunity to dive into these stuff. E.g., when you come across the “memory order”, you need to google a lot to really understand it, but it is indeed rewarding.

(2) C++ is actively evolving (C++03, C++11, C++14, C++17 …). Before C++ 11, i.e., modern C++, the main selling point of C++ is object-oriented and powerful template. But after that, C++introduces a lot features, and it becomes more and more complicated. E.g., the code may has different behaviors between C++14 and C++17 (please refer here) . Why do we bother to learn it since it is so intricate? Personally, I think it will give us a huge confidence: if you can harness C++ proficiently, is there any other language you can’t master?

(3) Because C++ is an old but popular language, there are fruitful resource which others can’t compete. From Open Source code to classical books, you can have so many references to help polishing your code skills. BTW, reading some works is a really enjoyment, not only assist you improve programming, but also teach how to write a good essay.

Hope this small article can let you take into learning C++ when you are free!