Update in-tree libosmium dependency to 2.5.4

The latest releases have some critical fixes, see the changelog:
https://github.com/osmcode/libosmium/blob/v2.5.4/CHANGELOG.md

Merge commit 'afdf8e7b21fbaf597e91d9d8a7542635e60ee9a1' into use_libosmium_2_5_4
This commit is contained in:
Daniel J. Hofmann
2016-01-05 12:00:40 +01:00
171 changed files with 7150 additions and 3988 deletions
@@ -50,7 +50,9 @@ namespace osmium {
struct impl_base {
virtual ~impl_base() = default;
virtual void call() = 0;
virtual bool call() {
return true;
}
}; // struct impl_base
@@ -58,28 +60,38 @@ namespace osmium {
template <typename F>
struct impl_type : impl_base {
F m_functor;
impl_type(F&& functor) :
m_functor(std::move(functor)) {
explicit impl_type(F&& functor) :
m_functor(std::forward<F>(functor)) {
}
void call() override {
bool call() override {
m_functor();
return false;
}
}; // struct impl_type
public:
// Constructor must not be "explicit" for wrapper
// to work seemlessly.
template <typename F>
function_wrapper(F&& f) :
impl(new impl_type<F>(std::move(f))) {
template <typename TFunction>
function_wrapper(TFunction&& f) :
impl(new impl_type<TFunction>(std::forward<TFunction>(f))) {
}
void operator()() {
impl->call();
// The integer parameter is only used to signal that we want
// the special function wrapper that makes the worker thread
// shut down.
function_wrapper(int) :
impl(new impl_base()) {
}
bool operator()() {
return impl->call();
}
function_wrapper() = default;
+42 -15
View File
@@ -54,6 +54,32 @@ namespace osmium {
*/
namespace thread {
namespace detail {
// Maximum number of allowed pool threads (just to keep the user
// from setting something silly).
constexpr const int max_pool_threads = 256;
inline int get_pool_size(int num_threads, int user_setting, unsigned hardware_concurrency) {
if (num_threads == 0) {
num_threads = user_setting ? user_setting : -2;
}
if (num_threads < 0) {
num_threads += hardware_concurrency;
}
if (num_threads < 1) {
num_threads = 1;
} else if (num_threads > max_pool_threads) {
num_threads = max_pool_threads;
}
return num_threads;
}
} // namespace detail
/**
* Thread pool.
*/
@@ -83,7 +109,6 @@ namespace osmium {
}; // class thread_joiner
std::atomic<bool> m_done;
osmium::thread::Queue<function_wrapper> m_work_queue;
std::vector<std::thread> m_threads;
thread_joiner m_joiner;
@@ -91,11 +116,15 @@ namespace osmium {
void worker_thread() {
osmium::thread::set_thread_name("_osmium_worker");
while (!m_done) {
while (true) {
function_wrapper task;
m_work_queue.wait_and_pop_with_timeout(task);
if (task) {
task();
if (task()) {
// The called tasks returns true only when the
// worker thread should shut down.
return;
}
}
}
}
@@ -113,26 +142,17 @@ namespace osmium {
* In all cases the minimum number of threads in the pool is 1.
*/
explicit Pool(int num_threads, size_t max_queue_size) :
m_done(false),
m_work_queue(max_queue_size, "work"),
m_threads(),
m_joiner(m_threads),
m_num_threads(num_threads) {
if (m_num_threads == 0) {
m_num_threads = osmium::config::get_pool_threads();
}
if (m_num_threads <= 0) {
m_num_threads = std::max(1, static_cast<int>(std::thread::hardware_concurrency()) + m_num_threads);
}
m_num_threads(detail::get_pool_size(num_threads, osmium::config::get_pool_threads(), std::thread::hardware_concurrency())) {
try {
for (int i = 0; i < m_num_threads; ++i) {
m_threads.push_back(std::thread(&Pool::worker_thread, this));
}
} catch (...) {
m_done = true;
shutdown_all_workers();
throw;
}
}
@@ -147,8 +167,15 @@ namespace osmium {
return pool;
}
void shutdown_all_workers() {
for (int i = 0; i < m_num_threads; ++i) {
// The special function wrapper makes a worker shut down.
m_work_queue.push(function_wrapper{0});
}
}
~Pool() {
m_done = true;
shutdown_all_workers();
m_work_queue.shutdown();
}
+9 -2
View File
@@ -75,6 +75,9 @@ namespace osmium {
/// The largest size the queue has been so far.
size_t m_largest_size;
/// The number of times push() was called on the queue.
std::atomic<int> m_push_counter;
/// The number of times the queue was full and a thread pushing
/// to the queue was blocked.
std::atomic<int> m_full_counter;
@@ -89,7 +92,7 @@ namespace osmium {
* 0 for an unlimited size.
* @param name Optional name for this queue. (Used for debugging.)
*/
Queue(size_t max_size = 0, const std::string& name = "") :
explicit Queue(size_t max_size = 0, const std::string& name = "") :
m_max_size(max_size),
m_name(name),
m_mutex(),
@@ -99,6 +102,7 @@ namespace osmium {
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
,
m_largest_size(0),
m_push_counter(0),
m_full_counter(0)
#endif
{
@@ -107,7 +111,7 @@ namespace osmium {
~Queue() {
shutdown();
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
std::cerr << "queue '" << m_name << "' with max_size=" << m_max_size << " had largest size " << m_largest_size << " and was full " << m_full_counter << " times\n";
std::cerr << "queue '" << m_name << "' with max_size=" << m_max_size << " had largest size " << m_largest_size << " and was full " << m_full_counter << " times in " << m_push_counter << " push() calls\n";
#endif
}
@@ -116,6 +120,9 @@ namespace osmium {
* call will block if the queue is full.
*/
void push(T value) {
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
++m_push_counter;
#endif
if (m_max_size) {
while (size() >= m_max_size) {
std::this_thread::sleep_for(full_queue_sleep_duration);
+33 -4
View File
@@ -49,7 +49,7 @@ namespace osmium {
* the exception stored in the future if there was one. Otherwise it
* will just return.
*/
template <class T>
template <typename T>
inline void check_for_exception(std::future<T>& future) {
if (future.valid() && future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
future.get();
@@ -60,7 +60,7 @@ namespace osmium {
* Wait until the given future becomes ready. Will block if the future
* is not ready. Can be called more than once unlike future.get().
*/
template <class T>
template <typename T>
inline void wait_until_done(std::future<T>& future) {
if (future.valid()) {
future.get();
@@ -71,15 +71,44 @@ namespace osmium {
* Set name of current thread for debugging. This only works on Linux.
*/
#ifdef __linux__
inline void set_thread_name(const char* name) {
inline void set_thread_name(const char* name) noexcept {
prctl(PR_SET_NAME, name, 0, 0, 0);
}
#else
inline void set_thread_name(const char*) {
inline void set_thread_name(const char*) noexcept {
// intentionally left blank
}
#endif
class thread_handler {
std::thread m_thread;
public:
thread_handler() :
m_thread() {
}
template <typename TFunction, typename... TArgs>
explicit thread_handler(TFunction&& f, TArgs&&... args) :
m_thread(std::forward<TFunction>(f), std::forward<TArgs>(args)...) {
}
thread_handler(const thread_handler&) = delete;
thread_handler& operator=(const thread_handler&) = delete;
thread_handler(thread_handler&&) = default;
thread_handler& operator=(thread_handler&&) = default;
~thread_handler() {
if (m_thread.joinable()) {
m_thread.join();
}
}
}; // class thread_handler
} // namespace thread
} // namespace osmium