Browse Source

Core thread now runs using the thread pool

Marko Pintera 11 years ago
parent
commit
11c7630162

+ 0 - 19
CamelotCore/Include/CmCoreThread.h

@@ -106,17 +106,6 @@ public:
 	 */
 	 */
 	CM_EXPORT FrameAlloc* getFrameAlloc() const;
 	CM_EXPORT FrameAlloc* getFrameAlloc() const;
 private:
 private:
-	class CoreThreadWorkerFunc CM_THREAD_WORKER_INHERIT
-	{
-	public:
-		CoreThreadWorkerFunc(CoreThread* owner);
-
-		void operator()();
-
-	private:
-		CoreThread* mOwner;
-	};
-
 	// Double buffered frame allocators - Means sim thread cannot be more than 1 frame ahead of core thread
 	// Double buffered frame allocators - Means sim thread cannot be more than 1 frame ahead of core thread
 	// (If that changes you should be able to easily add more)
 	// (If that changes you should be able to easily add more)
 	FrameAlloc* mFrameAllocs[2]; 
 	FrameAlloc* mFrameAllocs[2]; 
@@ -125,23 +114,15 @@ private:
 	static CM_THREADLOCAL AccessorContainer* mAccessor;
 	static CM_THREADLOCAL AccessorContainer* mAccessor;
 	Vector<AccessorContainer*>::type mAccessors;
 	Vector<AccessorContainer*>::type mAccessors;
 
 
-	CoreThreadWorkerFunc* mCoreThreadFunc;
-	volatile bool mCoreThreadStarted;
 	volatile bool mCoreThreadShutdown;
 	volatile bool mCoreThreadShutdown;
 
 
 	CM_THREAD_ID_TYPE mCoreThreadId;
 	CM_THREAD_ID_TYPE mCoreThreadId;
-	CM_THREAD_SYNCHRONISER(mCoreThreadStartCondition)
-	CM_MUTEX(mCoreThreadStartMutex)
 	CM_MUTEX(mCommandQueueMutex)
 	CM_MUTEX(mCommandQueueMutex)
 	CM_MUTEX(mAccessorMutex)
 	CM_MUTEX(mAccessorMutex)
 	CM_THREAD_SYNCHRONISER(mCommandReadyCondition)
 	CM_THREAD_SYNCHRONISER(mCommandReadyCondition)
 	CM_MUTEX(mCommandNotifyMutex)
 	CM_MUTEX(mCommandNotifyMutex)
 	CM_THREAD_SYNCHRONISER(mCommandCompleteCondition)
 	CM_THREAD_SYNCHRONISER(mCommandCompleteCondition)
 
 
-#if CM_THREAD_SUPPORT
-	CM_THREAD_TYPE* mCoreThread;
-#endif
-
 	CommandQueue<CommandQueueSync>* mCommandQueue;
 	CommandQueue<CommandQueueSync>* mCommandQueue;
 
 
 	UINT32 mMaxCommandNotifyId; // ID that will be assigned to the next command with a notifier callback
 	UINT32 mMaxCommandNotifyId; // ID that will be assigned to the next command with a notifier callback

+ 0 - 2
CamelotCore/Source/BsThreadPolicy.cpp

@@ -5,12 +5,10 @@ namespace BansheeEngine
 	void ThreadBansheePolicy::onThreadStarted(const String& name) 
 	void ThreadBansheePolicy::onThreadStarted(const String& name) 
 	{
 	{
 		MemStack::beginThread();
 		MemStack::beginThread();
-		Profiler::instance().beginThread(name.c_str());
 	}
 	}
 
 
 	void ThreadBansheePolicy::onThreadEnded(const String& name) 
 	void ThreadBansheePolicy::onThreadEnded(const String& name) 
 	{
 	{
-		Profiler::instance().endThread();
 		MemStack::endThread();
 		MemStack::endThread();
 	}
 	}
 }
 }

+ 2 - 2
CamelotCore/Source/CmApplication.cpp

@@ -58,7 +58,7 @@ namespace BansheeEngine
 		MemStack::beginThread();
 		MemStack::beginThread();
 
 
 		Profiler::startUp(cm_new<Profiler>());
 		Profiler::startUp(cm_new<Profiler>());
-		ThreadPool<ThreadBansheePolicy>::startUp(cm_new<ThreadPool<ThreadBansheePolicy>>(numWorkerThreads));
+		ThreadPool::startUp(cm_new<TThreadPool<ThreadBansheePolicy>>(numWorkerThreads));
 		StringTable::startUp(cm_new<StringTable>());
 		StringTable::startUp(cm_new<StringTable>());
 		DeferredCallManager::startUp(cm_new<DeferredCallManager>());
 		DeferredCallManager::startUp(cm_new<DeferredCallManager>());
 		Time::startUp(cm_new<Time>());
 		Time::startUp(cm_new<Time>());
@@ -193,7 +193,7 @@ namespace BansheeEngine
 		DeferredCallManager::shutDown();
 		DeferredCallManager::shutDown();
 		StringTable::shutDown();
 		StringTable::shutDown();
 
 
-		ThreadPool<ThreadBansheePolicy>::shutDown();
+		ThreadPool::shutDown();
 		Profiler::shutDown();
 		Profiler::shutDown();
 		MemStack::endThread();
 		MemStack::endThread();
 		Platform::shutDown();
 		Platform::shutDown();

+ 3 - 51
CamelotCore/Source/CmCoreThread.cpp

@@ -1,4 +1,5 @@
 #include "CmCoreThread.h"
 #include "CmCoreThread.h"
+#include "BsThreadPool.h"
 
 
 using namespace std::placeholders;
 using namespace std::placeholders;
 
 
@@ -7,9 +8,7 @@ namespace BansheeEngine
 	CM_THREADLOCAL CoreThread::AccessorContainer* CoreThread::mAccessor = nullptr;
 	CM_THREADLOCAL CoreThread::AccessorContainer* CoreThread::mAccessor = nullptr;
 
 
 	CoreThread::CoreThread()
 	CoreThread::CoreThread()
-		: mCoreThreadFunc(nullptr)
-		, mCoreThreadStarted(false)
-		, mCoreThreadShutdown(false)
+		: mCoreThreadShutdown(false)
 		, mCommandQueue(nullptr)
 		, mCommandQueue(nullptr)
 		, mMaxCommandNotifyId(0)
 		, mMaxCommandNotifyId(0)
 		, mSyncedCoreAccessor(nullptr)
 		, mSyncedCoreAccessor(nullptr)
@@ -53,17 +52,8 @@ namespace BansheeEngine
 	void CoreThread::initCoreThread()
 	void CoreThread::initCoreThread()
 	{
 	{
 #if !CM_FORCE_SINGLETHREADED_RENDERING
 #if !CM_FORCE_SINGLETHREADED_RENDERING
-		mCoreThreadFunc = cm_new<CoreThreadWorkerFunc>(this);
-
 #if CM_THREAD_SUPPORT
 #if CM_THREAD_SUPPORT
-		CM_THREAD_CREATE(t, *mCoreThreadFunc);
-		mCoreThread = t;
-
-		CM_LOCK_MUTEX_NAMED(mCoreThreadStartMutex, lock);
-
-		while(!mCoreThreadStarted)
-			CM_THREAD_WAIT(mCoreThreadStartCondition, mCoreThreadStartMutex, lock);
-
+		ThreadPool::instance().run("Core", std::bind(&CoreThread::runCoreThread, this));
 #else
 #else
 		CM_EXCEPT(InternalErrorException, "Attempting to start a core thread but application isn't compiled with thread support.");
 		CM_EXCEPT(InternalErrorException, "Attempting to start a core thread but application isn't compiled with thread support.");
 #endif
 #endif
@@ -73,19 +63,9 @@ namespace BansheeEngine
 	void CoreThread::runCoreThread()
 	void CoreThread::runCoreThread()
 	{
 	{
 #if !CM_FORCE_SINGLETHREADED_RENDERING
 #if !CM_FORCE_SINGLETHREADED_RENDERING
-		MemStack::beginThread();
-
 		mCoreThreadId = CM_THREAD_CURRENT_ID;
 		mCoreThreadId = CM_THREAD_CURRENT_ID;
 		mSyncedCoreAccessor = cm_new<CoreThreadAccessor<CommandQueueSync>>(CM_THREAD_CURRENT_ID);
 		mSyncedCoreAccessor = cm_new<CoreThreadAccessor<CommandQueueSync>>(CM_THREAD_CURRENT_ID);
 
 
-		{
-			CM_LOCK_MUTEX(mCoreThreadStartMutex);
-
-			mCoreThreadStarted = true;
-		}
-
-		CM_THREAD_NOTIFY_ALL(mCoreThreadStartCondition)
-
 		while(true)
 		while(true)
 		{
 		{
 			// Wait until we get some ready commands
 			// Wait until we get some ready commands
@@ -98,7 +78,6 @@ namespace BansheeEngine
 					if(mCoreThreadShutdown)
 					if(mCoreThreadShutdown)
 					{
 					{
 						cm_delete(mSyncedCoreAccessor);
 						cm_delete(mSyncedCoreAccessor);
-						MemStack::endThread();
 						return;
 						return;
 					}
 					}
 
 
@@ -126,20 +105,8 @@ namespace BansheeEngine
 		// Wake all threads. They will quit after they see the shutdown flag
 		// Wake all threads. They will quit after they see the shutdown flag
 		CM_THREAD_NOTIFY_ALL(mCommandReadyCondition);
 		CM_THREAD_NOTIFY_ALL(mCommandReadyCondition);
 
 
-		CM_THREAD_JOIN((*mCoreThread));
-		CM_THREAD_DESTROY(mCoreThread);
-
-		mCoreThread = nullptr;
 		mCoreThreadId = CM_THREAD_CURRENT_ID;
 		mCoreThreadId = CM_THREAD_CURRENT_ID;
-
-		if(mCoreThreadFunc != nullptr)
-		{
-			cm_delete(mCoreThreadFunc);
-			mCoreThreadFunc = nullptr;
-		}
 #endif
 #endif
-
-		mCoreThreadStarted = false;
 	}
 	}
 
 
 	CoreAccessorPtr CoreThread::getAccessor()
 	CoreAccessorPtr CoreThread::getAccessor()
@@ -311,19 +278,4 @@ namespace BansheeEngine
 			CM_EXCEPT(InternalErrorException, "This method cannot be accessed from the core thread.");
 			CM_EXCEPT(InternalErrorException, "This method cannot be accessed from the core thread.");
 #endif
 #endif
 	}
 	}
-
-	/************************************************************************/
-	/* 								THREAD WORKER                      		*/
-	/************************************************************************/
-
-	CoreThread::CoreThreadWorkerFunc::CoreThreadWorkerFunc(CoreThread* owner)
-		:mOwner(owner)
-	{
-		assert(mOwner != nullptr);
-	}
-
-	void CoreThread::CoreThreadWorkerFunc::operator()()
-	{
-		mOwner->runCoreThread();
-	}
 }
 }

+ 11 - 7
CamelotUtility/Include/BsThreadPool.h

@@ -11,6 +11,7 @@ namespace BansheeEngine
 		PooledThread(const String& name);
 		PooledThread(const String& name);
 		virtual ~PooledThread();
 		virtual ~PooledThread();
 
 
+		void initialize();
 		void start(std::function<void()> workerMethod);
 		void start(std::function<void()> workerMethod);
 		void run();
 		void run();
 		void destroy();
 		void destroy();
@@ -57,11 +58,11 @@ namespace BansheeEngine
 		}
 		}
 	};
 	};
 
 
-	class CM_UTILITY_EXPORT ThreadPoolBase : public Module<ThreadPoolBase>
+	class CM_UTILITY_EXPORT ThreadPool : public Module<ThreadPool>
 	{
 	{
 	public:
 	public:
-		ThreadPoolBase(UINT32 threadCapacity, UINT32 maxCapacity = 16, UINT32 idleTimeout = 60);
-		virtual ~ThreadPoolBase();
+		ThreadPool(UINT32 threadCapacity, UINT32 maxCapacity = 16, UINT32 idleTimeout = 60);
+		virtual ~ThreadPool();
 
 
 		void run(const String& name, std::function<void()> workerMethod);
 		void run(const String& name, std::function<void()> workerMethod);
 
 
@@ -96,11 +97,11 @@ namespace BansheeEngine
 	};
 	};
 
 
 	template<class ThreadPolicy = ThreadNoPolicy>
 	template<class ThreadPolicy = ThreadNoPolicy>
-	class ThreadPool : public ThreadPoolBase
+	class TThreadPool : public ThreadPool
 	{
 	{
 	public:
 	public:
-		ThreadPool(UINT32 threadCapacity, UINT32 maxCapacity = 16, UINT32 idleTimeout = 60)
-			:ThreadPoolBase(threadCapacity, maxCapacity, idleTimeout)
+		TThreadPool(UINT32 threadCapacity, UINT32 maxCapacity = 16, UINT32 idleTimeout = 60)
+			:ThreadPool(threadCapacity, maxCapacity, idleTimeout)
 		{
 		{
 
 
 		}
 		}
@@ -108,7 +109,10 @@ namespace BansheeEngine
 	protected:
 	protected:
 		PooledThread* createThread(const String& name)
 		PooledThread* createThread(const String& name)
 		{
 		{
-			return cm_new<TPooledThread<ThreadPolicy>>(name);
+			PooledThread* newThread = cm_new<TPooledThread<ThreadPolicy>>(name);
+			newThread->initialize();
+
+			return newThread;
 		}
 		}
 	};
 	};
 }
 }

+ 20 - 16
CamelotUtility/Source/BsThreadPool.cpp

@@ -5,8 +5,15 @@ namespace BansheeEngine
 	PooledThread::PooledThread(const String& name)
 	PooledThread::PooledThread(const String& name)
 		:mName(name), mIdle(true), mThreadStarted(false),
 		:mName(name), mIdle(true), mThreadStarted(false),
 			mThreadReady(false), mIdleTime(0)
 			mThreadReady(false), mIdleTime(0)
+	{ }
+
+	PooledThread::~PooledThread()
+	{ }
+
+	void PooledThread::initialize()
 	{
 	{
 		CM_THREAD_CREATE(t, std::bind(&PooledThread::run, this));
 		CM_THREAD_CREATE(t, std::bind(&PooledThread::run, this));
+		mThread = t;
 
 
 		CM_LOCK_MUTEX_NAMED(mMutex, lock);
 		CM_LOCK_MUTEX_NAMED(mMutex, lock);
 
 
@@ -14,16 +21,14 @@ namespace BansheeEngine
 			CM_THREAD_WAIT(mStartedCond, mMutex, lock);
 			CM_THREAD_WAIT(mStartedCond, mMutex, lock);
 	}
 	}
 
 
-	PooledThread::~PooledThread()
-	{
-
-	}
-
 	void PooledThread::start(std::function<void()> workerMethod)
 	void PooledThread::start(std::function<void()> workerMethod)
 	{
 	{
 		{
 		{
 			CM_LOCK_MUTEX(mMutex);
 			CM_LOCK_MUTEX(mMutex);
+
 			mWorkerMethod = workerMethod;
 			mWorkerMethod = workerMethod;
+			mIdle = false;
+			mIdleTime = std::time(nullptr);
 			mThreadReady = true;
 			mThreadReady = true;
 		}
 		}
 
 
@@ -58,7 +63,6 @@ namespace BansheeEngine
 				}
 				}
 
 
 				worker = mWorkerMethod;
 				worker = mWorkerMethod;
-				mIdle = false;
 			}
 			}
 
 
 			worker();
 			worker();
@@ -105,23 +109,23 @@ namespace BansheeEngine
 		mName = name;
 		mName = name;
 	}
 	}
 
 
-	ThreadPoolBase::ThreadPoolBase(UINT32 threadCapacity, UINT32 maxCapacity, UINT32 idleTimeout)
+	ThreadPool::ThreadPool(UINT32 threadCapacity, UINT32 maxCapacity, UINT32 idleTimeout)
 		:mDefaultCapacity(threadCapacity), mMaxCapacity(maxCapacity), mIdleTimeout(idleTimeout), mAge(0)
 		:mDefaultCapacity(threadCapacity), mMaxCapacity(maxCapacity), mIdleTimeout(idleTimeout), mAge(0)
 	{
 	{
 
 
 	}
 	}
 
 
-	ThreadPoolBase::~ThreadPoolBase()
+	ThreadPool::~ThreadPool()
 	{
 	{
 		stopAll();
 		stopAll();
 	}
 	}
 
 
-	void ThreadPoolBase::run(const String& name, std::function<void()> workerMethod)
+	void ThreadPool::run(const String& name, std::function<void()> workerMethod)
 	{
 	{
 		getThread(name)->start(workerMethod);
 		getThread(name)->start(workerMethod);
 	}
 	}
 
 
-	void ThreadPoolBase::stopAll()
+	void ThreadPool::stopAll()
 	{
 	{
 		CM_LOCK_MUTEX(mMutex);
 		CM_LOCK_MUTEX(mMutex);
 		for(auto& thread : mThreads)
 		for(auto& thread : mThreads)
@@ -132,7 +136,7 @@ namespace BansheeEngine
 		mThreads.clear();
 		mThreads.clear();
 	}
 	}
 
 
-	void ThreadPoolBase::clearUnused()
+	void ThreadPool::clearUnused()
 	{
 	{
 		CM_LOCK_MUTEX(mMutex);
 		CM_LOCK_MUTEX(mMutex);
 		mAge = 0;
 		mAge = 0;
@@ -178,13 +182,13 @@ namespace BansheeEngine
 		mThreads.insert(mThreads.end(), activeThreads.begin(), activeThreads.end());
 		mThreads.insert(mThreads.end(), activeThreads.begin(), activeThreads.end());
 	}
 	}
 
 
-	void ThreadPoolBase::destroyThread(PooledThread* thread)
+	void ThreadPool::destroyThread(PooledThread* thread)
 	{
 	{
 		thread->destroy();
 		thread->destroy();
 		cm_delete(thread);
 		cm_delete(thread);
 	}
 	}
 
 
-	PooledThread* ThreadPoolBase::getThread(const String& name)
+	PooledThread* ThreadPool::getThread(const String& name)
 	{
 	{
 		UINT32 age = 0;
 		UINT32 age = 0;
 		{
 		{
@@ -219,7 +223,7 @@ namespace BansheeEngine
 		return newThread;
 		return newThread;
 	}
 	}
 
 
-	UINT32 ThreadPoolBase::getNumAvailable() const
+	UINT32 ThreadPool::getNumAvailable() const
 	{
 	{
 		UINT32 numAvailable = 0;
 		UINT32 numAvailable = 0;
 
 
@@ -233,7 +237,7 @@ namespace BansheeEngine
 		return numAvailable;
 		return numAvailable;
 	}
 	}
 
 
-	UINT32 ThreadPoolBase::getNumActive() const
+	UINT32 ThreadPool::getNumActive() const
 	{
 	{
 		UINT32 numActive = 0;
 		UINT32 numActive = 0;
 
 
@@ -247,7 +251,7 @@ namespace BansheeEngine
 		return numActive;
 		return numActive;
 	}
 	}
 
 
-	UINT32 ThreadPoolBase::getNumAllocated() const
+	UINT32 ThreadPool::getNumAllocated() const
 	{
 	{
 		CM_LOCK_MUTEX(mMutex);
 		CM_LOCK_MUTEX(mMutex);