Skip to content

Commit

Permalink
Merge pull request #387 from evoskuil/master
Browse files Browse the repository at this point in the history
Eliminate boost::thread (no longer required due to thread_local).
  • Loading branch information
evoskuil committed Mar 17, 2024
2 parents 0d74e52 + 5810a01 commit a49a766
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 70 deletions.
24 changes: 3 additions & 21 deletions include/bitcoin/network/async/thread.hpp
Expand Up @@ -20,26 +20,12 @@
#define LIBBITCOIN_NETWORK_ASYNC_THREAD_HPP

#include <memory>
#include <boost/thread.hpp>
#include <bitcoin/system.hpp>
#include <bitcoin/network/define.hpp>

namespace libbitcoin {
namespace network {

////// Adapted from: stackoverflow.com/a/18298965/1172329
////#ifndef thread_local
//// #if (__STDC_VERSION__ >= 201112) && (!defined __STDC_NO_THREADS__)
//// #define thread_local _Thread_local
//// #elif defined(_MSC_VER)
//// #define thread_local __declspec(thread)
//// #elif defined(__GNUC__)
//// #define thread_local __thread
//// #else
//// #error "Cannot define thread_local"
//// #endif
////#endif

enum class thread_priority
{
high,
Expand All @@ -48,15 +34,11 @@ enum class thread_priority
lowest
};

// Boost thread is used because of thread_specific_ptr limitation:
// stackoverflow.com/q/22448022/1172329
typedef boost::thread thread;
// Always at least 1 (guards against irrational API return).
BCT_API size_t cores() NOEXCEPT;

// Set thread priority for the current thread.
BCT_API void set_priority(thread_priority priority) NOEXCEPT;
BCT_API thread_priority priority(bool priority) NOEXCEPT;
BCT_API size_t thread_default(size_t configured) NOEXCEPT;
BCT_API size_t thread_ceiling(size_t configured) NOEXCEPT;
BCT_API size_t thread_floor(size_t configured) NOEXCEPT;

} // namespace network
} // namespace libbitcoin
Expand Down
4 changes: 2 additions & 2 deletions include/bitcoin/network/async/threadpool.hpp
Expand Up @@ -19,7 +19,7 @@
#ifndef LIBBITCOIN_NETWORK_ASYNC_THREADPOOL_HPP
#define LIBBITCOIN_NETWORK_ASYNC_THREADPOOL_HPP

#include <memory>
#include <thread>
#include <bitcoin/system.hpp>
#include <bitcoin/network/async/asio.hpp>
#include <bitcoin/network/async/thread.hpp>
Expand Down Expand Up @@ -64,7 +64,7 @@ class BCT_API threadpool final
asio::io_context service_{};

// These are not thread safe.
std::vector<thread> threads_{};
std::vector<std::thread> threads_{};
work_guard work_;
};

Expand Down
1 change: 0 additions & 1 deletion include/bitcoin/network/boost.hpp
Expand Up @@ -45,6 +45,5 @@
#include <boost/circular_buffer.hpp>
#include <boost/regex.hpp>
#include <boost/system/error_code.hpp>
#include <boost/thread.hpp>

#endif
46 changes: 2 additions & 44 deletions src/async/thread.cpp
Expand Up @@ -18,7 +18,6 @@
*/
#include <bitcoin/network/async/thread.hpp>

#include <algorithm>
#include <thread>

#ifdef HAVE_MSC
Expand Down Expand Up @@ -71,50 +70,9 @@ void set_priority(thread_priority priority) NOEXCEPT
#endif
}

thread_priority priority(bool priority) NOEXCEPT
size_t cores() NOEXCEPT
{
return priority ? thread_priority::high : thread_priority::normal;
}

inline size_t cores()
{
// Cores must be at least 1 (guards against irrational API return).
return std::max(std::thread::hardware_concurrency(), 1u);
}

// This is used to default the number of threads to the number of cores and to
// ensure that no less than one thread is configured.
size_t thread_default(size_t configured) NOEXCEPT
{
if (is_zero(configured))
return cores();

// Configured but no less than 1.
return std::max(configured, one);
}

// This is used to ensure that threads does not exceed cores in the case of
// parallel work distribution, while allowing the user to reduce parallelism so
// as not to monopolize the processor. It also makes optimal config easy (0).
size_t thread_ceiling(size_t configured) NOEXCEPT
{
if (is_zero(configured))
return cores();

// Cores/1 but no more than configured.
return std::min(configured, cores());
}

// This is used to ensure that at least a minimum required number of threads is
// allocated, so that thread starvation does not occur. It also allows the user
// to increase threads above minimum. It always ensures at least core threads.
size_t thread_floor(size_t configured) NOEXCEPT
{
if (is_zero(configured))
return cores();

// Configured but no less than cores/1.
return std::max(configured, cores());
return std::max(std::thread::hardware_concurrency(), 1_u32);
}

} // namespace network
Expand Down
5 changes: 3 additions & 2 deletions src/async/threadpool.cpp
Expand Up @@ -18,6 +18,7 @@
*/
#include <bitcoin/network/async/threadpool.hpp>

#include <thread>
#include <bitcoin/system.hpp>
#include <bitcoin/network/async/asio.hpp>
#include <bitcoin/network/async/thread.hpp>
Expand All @@ -42,7 +43,7 @@ threadpool::threadpool(size_t number_threads, thread_priority priority) NOEXCEPT
{
for (size_t thread = 0; thread < number_threads; ++thread)
{
threads_.push_back(network::thread([this, priority]() NOEXCEPT
threads_.push_back(std::thread([this, priority]() NOEXCEPT
{
set_priority(priority);

Expand Down Expand Up @@ -73,7 +74,7 @@ void threadpool::stop() NOEXCEPT

bool threadpool::join() NOEXCEPT
{
const auto this_id = boost::this_thread::get_id();
const auto this_id = std::this_thread::get_id();

for (auto& thread: threads_)
{
Expand Down

0 comments on commit a49a766

Please sign in to comment.