This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/extern/audaspace/include/util/ThreadPool.h
Joseph Eagar 173f5f94ff Sculpt dyntopo:
Seperate enabling PBVH_BMESH from enabling DynTopo:

* Created a new option to globally disabled
  DynTopo.
* The DynTopo panel header now reads "Dynamic Mode",
  to hopefully signal that turning on PBVH_BMESH is
  a seperate step from enabling or disabling DynTopo
  itself.
* The first checkbox in the panel is "DynTopo" so it
  should be clear enough (it's on by default, with multiple
  layers of file versioning checks).

PBVH_BMesh's undo system:

* CD_MESH_ID layers are now permanently saved once
  they are created (by default they are not).  This
  fixed a *lot* of bugs:

  Before this the undo system had to save maps between
  mesh indices and mesh IDs on transitioning
  between sculpt and global undo steps.  This was
  extremely error prone, and it simply wasn't possible
  to cover all of the corner cases

* Note that there is still an odd bug where the first
  global undo push after a sculpt step gets ignored,
  I dunno what's up with this.

* Dyntopo undo should be nearly (hopefully completely)
  bug-free after this commit.

C++20

* Made a few small changes to get blender to compile
  with c++20.  std::result_of was removed, had to
  replace a couple of usages of it with std::invoke_result.

* I'm planning to do some design studies on rewriting
  sculpt into C++.

* I strongly suspect we are going to need C++20'a new
  concepts feature if we move sculpt into C++.
  I'm planning to do some design studies on how
  that might work.
2021-09-15 01:41:03 -07:00

126 lines
3.0 KiB
C++

/*******************************************************************************
* Copyright 2015-2016 Juan Francisco Crespo Galán
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
#pragma once
/**
* @file ThreadPool.h
* @ingroup util
* The ThreadPool class.
*/
#include "Audaspace.h"
#include <mutex>
#include <condition_variable>
#include <vector>
#include <thread>
#include <queue>
#include <future>
#include <functional>
AUD_NAMESPACE_BEGIN
/**
* This represents pool of threads.
*/
class AUD_API ThreadPool
{
private:
/**
* A queue of tasks.
*/
std::queue<std::function<void()>> m_queue;
/**
* A vector of thread objects.
*/
std::vector<std::thread> m_threads;
/**
* A mutex for synchronization.
*/
std::mutex m_mutex;
/**
* A condition variable used to stop the threads when there are no tasks.
*/
std::condition_variable m_condition;
/**
* Stop flag.
*/
bool m_stopFlag;
/**
* The number fo threads.
*/
unsigned int m_numThreads;
// delete copy constructor and operator=
ThreadPool(const ThreadPool&) = delete;
ThreadPool& operator=(const ThreadPool&) = delete;
public:
/**
* Creates a new ThreadPool object.
* \param count The number of threads of the pool. It must not be 0.
*/
ThreadPool(unsigned int count);
virtual ~ThreadPool();
/**
* Enqueues a new task for the threads to realize.
* \param t A function that realices a task.
* \param args The arguments of the task.
* \return A future of the same type as the return type of the task.
*/
#if __cplusplus > 201703L
template<class T, class... Args>
std::future<typename std::invoke_result<T, Args...>::type> enqueue(T&& t, Args&&... args)
{
using pkgdTask = std::packaged_task<typename std::invoke_result<T, Args...>::type()>;
#else
template<class T, class... Args>
std::future<typename std::result_of<T(Args...)>::type> enqueue(T&& t, Args&&... args)
{
using pkgdTask = std::packaged_task<typename std::result_of<T(Args...)>::type()>;
#endif
std::shared_ptr<pkgdTask> task = std::make_shared<pkgdTask>(std::bind(std::forward<T>(t), std::forward<Args>(args)...));
auto result = task->get_future();
m_mutex.lock();
m_queue.emplace([task]() { (*task)(); });
m_mutex.unlock();
m_condition.notify_one();
return result;
}
/**
* Retrieves the number of threads of the pool.
* \return The number of threads.
*/
unsigned int getNumOfThreads();
private:
/**
* Worker thread function.
*/
void threadFunction();
};
AUD_NAMESPACE_END