<commit_before>/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France       *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: <EMAIL>                                        *
*                                                                              *
*******************************************************************************/

/*
 * IMPORTANT : The ThreadPool code (thread_pool.h and thread_pool.cpp) is
 * based on "A Simple c++11 threadpool implementation" found on github
 * (https://github.com/progschj/ThreadPool, latest commit : 9a42ec1 )
 * (c) 2012 <NAME>, <NAME>
 * It has been modified to fit to our purposes.
 * A copy of its license is provided in the following lines.
 */

/****************************************************************************
*Copyright (c) 2012 <NAME>, <NAME>                             *
*                                                                           *
*This software is provided 'as-is', without any express or implied          *
*warranty. In no event will the authors be held liable for any damages      *
*arising from the use of this software.                                     *
*                                                                           *
*Permission is granted to anyone to use this software for any purpose,      *
*including commercial applications, and to alter it and redistribute it     *
*freely, subject to the following restrictions:                             *
*                                                                           *
*1. The origin of this software must not be misrepresented; you must not    *
*claim that you wrote the original software. If you use this software       *
*in a product, an acknowledgment in the product documentation would be      *
*appreciated but is not required.                                           *
*                                                                           *
*2. Altered source versions must be plainly marked as such, and must not be *
*misrepresented as being the original software.                             *
*                                                                           *
*3. This notice may not be removed or altered from any source               *
*distribution.                                                              *
****************************************************************************/

#ifndef CGOGN_CORE_UTILS_THREADPOOL_H_
#define CGOGN_CORE_UTILS_THREADPOOL_H_

#include <vector>
#include <queue>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>

#include <cgogn/core/utils/logger.h>
#include <cgogn/core/utils/assert.h>
#include <cgogn/core/utils/thread.h>

namespace cgogn
{

class CGOGN_CORE_API ThreadPool final
{
public:

	ThreadPool();
	CGOGN_NOT_COPYABLE_NOR_MOVABLE(ThreadPool);

	template <class F, class... Args>
	auto enqueue(const F& f, Args&&... args)
	-> std::future<typename std::result_of<F(uint32, Args...)>::type>;

	std::vector<std::thread::id> threads_ids() const;
	~ThreadPool();

	inline std::size_t nb_threads() const
	{
		return workers_.size();
	}

private:

	// need to keep track of threads so we can join them
	std::vector<std::thread> workers_;
	// the task queue
	std::queue<std::function<void(uint32)>> tasks_;

	// synchronization
	std::mutex queue_mutex_;
	std::condition_variable condition_;
	bool stop_;
};

// add new work item to the pool
template <class F, class... Args>
auto ThreadPool::enqueue(const F& f, Args&&... args)
-> std::future<typename std::result_of<F(uint32, Args...)>::type>
{
	using return_type = typename std::result_of<F(uint32, Args...)>::type;

	auto task = std::make_shared<std::packaged_task<return_type(uint32)>>([f, &args...] (uint32 i)
	{
		f(i, std::forward<Args>(args)...);
	});

	std::future<return_type> res = task->get_future();
	{
		std::unique_lock<std::mutex> lock(queue_mutex_);
			// don't allow enqueueing after stopping the pool
		if (stop_)
		{
			cgogn_log_error("ThreadPool::enqueue") << "Enqueue on stopped ThreadPool.";
			cgogn_assert_not_reached("enqueue on stopped ThreadPool");
		}
		// Push work back on the queue
		tasks_.emplace([task] (uint32 i) { (*task)(i); });
	}
	// Notify a thread that there is new work to perform
	condition_.notify_one();
	return res;
}

} // namespace cgogn

#endif // CGOGN_CORE_UTILS_THREADPOOL_H_
<commit_msg>ThreadPool : using std::promise instead of packaged_task. Split into 2 cases  : returning or non-returning functions.<commit_after>/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France       *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: <EMAIL>                                        *
*                                                                              *
*******************************************************************************/

/*
 * IMPORTANT : The ThreadPool code (thread_pool.h and thread_pool.cpp) is
 * based on "A Simple c++11 threadpool implementation" found on github
 * (https://github.com/progschj/ThreadPool, latest commit : 9a42ec1 )
 * (c) 2012 <NAME>, <NAME>
 * It has been modified to fit to our purposes.
 * A copy of its license is provided in the following lines.
 */

/****************************************************************************
*Copyright (c) 2012 <NAME>, <NAME>                             *
*                                                                           *
*This software is provided 'as-is', without any express or implied          *
*warranty. In no event will the authors be held liable for any damages      *
*arising from the use of this software.                                     *
*                                                                           *
*Permission is granted to anyone to use this software for any purpose,      *
*including commercial applications, and to alter it and redistribute it     *
*freely, subject to the following restrictions:                             *
*                                                                           *
*1. The origin of this software must not be misrepresented; you must not    *
*claim that you wrote the original software. If you use this software       *
*in a product, an acknowledgment in the product documentation would be      *
*appreciated but is not required.                                           *
*                                                                           *
*2. Altered source versions must be plainly marked as such, and must not be *
*misrepresented as being the original software.                             *
*                                                                           *
*3. This notice may not be removed or altered from any source               *
*distribution.                                                              *
****************************************************************************/

#ifndef CGOGN_CORE_UTILS_THREADPOOL_H_
#define CGOGN_CORE_UTILS_THREADPOOL_H_

#include <vector>
#include <queue>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>

#include <cgogn/core/utils/logger.h>
#include <cgogn/core/utils/assert.h>
#include <cgogn/core/utils/thread.h>

namespace cgogn
{

class CGOGN_CORE_API ThreadPool final
{
public:

	ThreadPool();
	CGOGN_NOT_COPYABLE_NOR_MOVABLE(ThreadPool);

	template <class F, class... Args>
	typename std::enable_if<std::is_same<typename std::result_of<F(uint32, Args...)>::type,void>::value,std::future<void>>::type enqueue(const F& f, Args&&... args);
	template <class F, class... Args>
	typename std::enable_if<!std::is_same<typename std::result_of<F(uint32, Args...)>::type,void>::value,std::future<typename std::result_of<F(uint32, Args...)>::type>>::type enqueue(const F& f, Args&&... args);

	std::vector<std::thread::id> threads_ids() const;
	~ThreadPool();

	inline std::size_t nb_threads() const
	{
		return workers_.size();
	}

private:

	// need to keep track of threads so we can join them
	std::vector<std::thread> workers_;
	// the task queue
	std::queue<std::function<void(uint32)>> tasks_;

	// synchronization
	std::mutex queue_mutex_;
	std::condition_variable condition_;
	bool stop_;
};

// add new work item to the pool
template <class F, class... Args>
typename std::enable_if<!std::is_same<typename std::result_of<F(uint32, Args...)>::type,void>::value,std::future<typename std::result_of<F(uint32, Args...)>::type>>::type ThreadPool::enqueue(const F& f, Args&&... args)
{
	using return_type = typename std::result_of<F(uint32, Args...)>::type;

	auto p = std::make_shared<std::promise<return_type>>();
	auto res = p->get_future();
	std::function<return_type(uint32)> task([&f, &args...,p](uint32 i)
	{
		p->set_value(f(i, std::forward<Args>(args)...));
	});

	{
		std::unique_lock<std::mutex> lock(queue_mutex_);
			// don't allow enqueueing after stopping the pool
		if (stop_)
		{
			cgogn_log_error("ThreadPool::enqueue") << "Enqueue on stopped ThreadPool.";
			cgogn_assert_not_reached("enqueue on stopped ThreadPool");
		}
		// Push work back on the queue
		tasks_.emplace(std::move(task));
	}
	// Notify a thread that there is new work to perform
	condition_.notify_one();
	return res;
}

template <class F, class... Args>
typename std::enable_if<std::is_same<typename std::result_of<F(uint32, Args...)>::type,void>::value,std::future<void>>::type ThreadPool::enqueue(const F& f, Args&&... args)
{
	auto p = std::make_shared<std::promise<void>>();
	std::future<void> res = p->get_future();
	std::function<void(uint32)> task([&f, &args...,p](uint32 i)
	{
		f(i, std::forward<Args>(args)...);
		p->set_value();
	});

	{
		std::unique_lock<std::mutex> lock(queue_mutex_);
			// don't allow enqueueing after stopping the pool
		if (stop_)
		{
			cgogn_log_error("ThreadPool::enqueue") << "Enqueue on stopped ThreadPool.";
			cgogn_assert_not_reached("enqueue on stopped ThreadPool");
		}
		// Push work back on the queue
		tasks_.emplace(std::move(task));
	}
	// Notify a thread that there is new work to perform
	condition_.notify_one();
	return res;
}


} // namespace cgogn

#endif // CGOGN_CORE_UTILS_THREADPOOL_H_

{'fraction_non_alphanumeric': 0.14520067144819168, 'fraction_numerical': 0.00816419960323516, 'mean_word_length': 2.053109713487072, 'pattern_counts': {'":': 0, '<': 95, '<?xml version=': 0, '>': 96, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 80, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5806349', 'n_tokens_mistral': 3408, 'n_tokens_neox': 3215, 'n_words': 1084}