Is it possible thread support pthread and std::thread.

Discussion area about developing with Ogre2 branches (2.1, 2.2 and beyond)
Post Reply
longer
Kobold
Posts: 28
Joined: Tue Aug 19, 2014 10:46 am

Is it possible thread support pthread and std::thread.

Post by longer » Tue Jul 19, 2016 9:12 am

I check out the 2.* version and look a pthread mutex class.but not can not find pthread suppot at OgreThreadDefines.h the same at cmake parameter.
Boost and tbb is heavy to use.
Is any implement for pthread?

i think a pure pthread implement is usefull.lightweight and most unix family support it local.And same for c++11 thread,the vast majority of compiler support c++11 and a pure std::thread implement for ogre i think is great.

here is my self ogre thread define,it is use std::thread and pthread,at windows i use pthread-win.not pure,but can work:
OgreThreadDefinesMM.h

Code: Select all

/*-------------------------------------------------------------------------
This source file is a part of OGRE
(Object-oriented Graphics Rendering Engine)

For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE
-------------------------------------------------------------------------*/
#ifndef __OgreThreadDefinesMM_H__
#define __OgreThreadDefinesMM_H__

//////////////////////////////////////////////////////////////////////////
namespace mm
{
	// we not use the thread_local because a unknown macro duplication of name. 
	class mm_rw_lock
	{
	public:
		mm_rw_lock()
		{
			pthread_rwlock_init(&locker,NULL);
		}
		~mm_rw_lock()
		{
			pthread_rwlock_destroy(&locker);
		}
	public:
		void r_lock()
		{
			pthread_rwlock_rdlock(&locker);
		}
		void r_unlock()
		{
			pthread_rwlock_unlock(&locker);
		}
		void w_lock()
		{
			pthread_rwlock_wrlock(&locker);
		}
		void w_unlock()
		{
			pthread_rwlock_unlock(&locker);
		}
	private:
		pthread_rwlock_t locker;
	};
	class mm_r_auto_lock
	{
	public:
		explicit mm_r_auto_lock(mm_rw_lock& v)
			: locker(v)
		{
			locker.r_lock();
		}
		~mm_r_auto_lock()
		{
			locker.r_unlock();
		}
	private:
		mm_r_auto_lock();
		mm_r_auto_lock(const mm_r_auto_lock&);
		mm_r_auto_lock& operator=(const mm_r_auto_lock&);
	private:
		mm_rw_lock& locker;
	};
	class mm_w_auto_lock
	{
	public:
		explicit mm_w_auto_lock(mm_rw_lock& v)
			: locker(v)
		{
			locker.w_lock();
		}
		~mm_w_auto_lock()
		{
			locker.w_unlock();
		}
	private:
		mm_w_auto_lock();
		mm_w_auto_lock(const mm_w_auto_lock&);
		mm_w_auto_lock& operator=(const mm_w_auto_lock&);
	private:
		mm_rw_lock& locker;
	};
	//////////////////////////////////////////////////////////////////////////
	template<typename _T>
	class mm_thread_local
	{
	public:
		typedef _T T;
		typedef mm_thread_local<T> SelfType;
		typedef void(*mm_thread_local_destroy_func)(T*);
		mm_thread_local(mm_thread_local_destroy_func func)
			: v(NULL)
			, destroy_func(func)
		{
			pthread_key_create(&k,&mm_thread_local::__mm_thread_mm_thread_local_thread_key_free);
		}
		mm_thread_local()
			: destroy_func(NULL)
			, v(NULL)
		{
			pthread_key_create(&k,&mm_thread_local::__mm_thread_mm_thread_local_thread_key_free);
		}
		~mm_thread_local()
		{
			pthread_key_delete(k);
		}
	public:
		void set(T* v)
		{
			this->v = v;
			pthread_setspecific(k,this);
		}
		T* get()
		{
			SelfType* _this = (SelfType*)pthread_getspecific(k);
			if (_this)
			{
				return (T*)(_this->v);
			}
			return NULL;
		}
		void reset(T* v)
		{
			this->v = v;
			pthread_setspecific(k,this);
		}
	public:
		static void __mm_thread_mm_thread_local_thread_key_free(void* _arg)
		{
			SelfType* _this = (SelfType*)_arg;
			if (_this&&_this->destroy_func&&_this->v)
			{
				(*_this->destroy_func)((T*)_this->v);
				_this->v = NULL;
			}
		}
	private:
		pthread_key_t k;
		void* v;
		mm_thread_local_destroy_func destroy_func;
	};
	//////////////////////////////////////////////////////////////////////////
}
//////////////////////////////////////////////////////////////////////////
// we use cxx 11 thread lib for ogre thread impl.
#define OGRE_TOKEN_PASTE(x, y) x ## y
#define OGRE_TOKEN_PASTE_EXTRA(x, y) OGRE_TOKEN_PASTE(x, y)

#define OGRE_LOCK_AUTO_MUTEX std::unique_lock<std::recursive_mutex> ogreAutoMutexLock(OGRE_AUTO_MUTEX_NAME)
#define OGRE_LOCK_MUTEX(name) std::unique_lock<std::recursive_mutex> OGRE_TOKEN_PASTE_EXTRA(ogrenameLock, __LINE__) (name)
#define OGRE_LOCK_MUTEX_NAMED(mutexName, lockName) std::unique_lock<std::recursive_mutex> lockName(mutexName)
#define OGRE_THREAD_SYNCHRONISER(sync) std::condition_variable_any sync
#define OGRE_THREAD_SLEEP(ms) std::this_thread::sleep_for(std::chrono::milliseconds(ms))

#define OGRE_AUTO_MUTEX mutable std::recursive_mutex OGRE_AUTO_MUTEX_NAME
#define OGRE_MUTEX(name) mutable std::recursive_mutex name
#define OGRE_STATIC_MUTEX(name) static std::recursive_mutex name
#define OGRE_STATIC_MUTEX_INSTANCE(name) std::recursive_mutex name
// like OGRE_AUTO_MUTEX but mutex held by pointer
#define OGRE_AUTO_SHARED_MUTEX mutable std::recursive_mutex *OGRE_AUTO_MUTEX_NAME
#define OGRE_LOCK_AUTO_SHARED_MUTEX assert(OGRE_AUTO_MUTEX_NAME); std::recursive_mutex::scoped_lock ogreAutoMutexLock(*OGRE_AUTO_MUTEX_NAME)
#define OGRE_NEW_AUTO_SHARED_MUTEX assert(!OGRE_AUTO_MUTEX_NAME); OGRE_AUTO_MUTEX_NAME = new std::recursive_mutex()
#define OGRE_DELETE_AUTO_SHARED_MUTEX do { assert(OGRE_AUTO_MUTEX_NAME); delete OGRE_AUTO_MUTEX_NAME; } while (0)
#define OGRE_COPY_AUTO_SHARED_MUTEX(from) assert(!OGRE_AUTO_MUTEX_NAME); OGRE_AUTO_MUTEX_NAME = from
#define OGRE_SET_AUTO_SHARED_MUTEX_NULL OGRE_AUTO_MUTEX_NAME = 0
#define OGRE_MUTEX_CONDITIONAL(mutex) if (mutex)
#define OGRE_THREAD_WAIT(sync, mutex, lock) sync.wait(lock)
#define OGRE_THREAD_NOTIFY_ONE(sync) sync.notify_one()
#define OGRE_THREAD_NOTIFY_ALL(sync) sync.notify_all()
// Read-write mutex
#define OGRE_RW_MUTEX(name) mutable mm::mm_rw_lock name
#define OGRE_LOCK_RW_MUTEX_READ(name) mm::mm_r_auto_lock OGRE_TOKEN_PASTE_EXTRA(ogrenameLock, __LINE__) (name)
#define OGRE_LOCK_RW_MUTEX_WRITE(name) mm::mm_w_auto_lock OGRE_TOKEN_PASTE_EXTRA(ogrenameLock, __LINE__) (name)
// Thread-local pointer
#define OGRE_THREAD_POINTER(T, var) mm::mm_thread_local<T> var
#define OGRE_THREAD_POINTER_INIT(var) var(&deletePtr)
#define OGRE_THREAD_POINTER_VAR(T, var) mm::mm_thread_local<T> var (&deletePtr<T>)
#define OGRE_THREAD_POINTER_SET(var, expr) var.reset(expr)
#define OGRE_THREAD_POINTER_GET(var) var.get()
#define OGRE_THREAD_POINTER_DELETE(var) var.reset(0)
// Thread objects and related functions
#define OGRE_THREAD_TYPE std::thread
#define OGRE_THREAD_CREATE(name, worker) std::thread* name = OGRE_NEW_T(std::thread, Ogre::MEMCATEGORY_GENERAL)(worker)
#define OGRE_THREAD_DESTROY(name) OGRE_DELETE_T(name, thread, Ogre::MEMCATEGORY_GENERAL)
#define OGRE_THREAD_HARDWARE_CONCURRENCY std::thread::hardware_concurrency()
#define OGRE_THREAD_CURRENT_ID std::this_thread::get_id()
#define OGRE_THREAD_WORKER_INHERIT
// Utility
#define OGRE_THREAD_ID_TYPE std::thread::id
#define OGRE_THREAD_YIELD std::this_thread::yield()

#endif//__OgreThreadDefinesMM_H__
the OgreThreadDefines.h

Code: Select all

#ifndef __OgreThreadDefines_H__
#define __OgreThreadDefines_H__

#define OGRE_AUTO_MUTEX_NAME mutex
#if OGRE_THREAD_PROVIDER == 0
	#include "OgreThreadDefinesNone.h"
#elif OGRE_THREAD_PROVIDER == 1
	#include "OgreThreadDefinesBoost.h"
#elif OGRE_THREAD_PROVIDER == 2
	#include "OgreThreadDefinesPoco.h"
#elif OGRE_THREAD_PROVIDER == 3
	#include "OgreThreadDefinesTBB.h"
#elif OGRE_THREAD_PROVIDER == 4
	#include "OgreThreadDefinesMM.h"
#endif

#endif
0 x

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 3997
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 192
Contact:

Re: Is it possible thread support pthread and std::thread.

Post by dark_sylinc » Tue Jul 19, 2016 5:08 pm

In light of this question I just updated the FAQ:
There is the "old threading" code and the "new" threading code.

The old threading code can be enabled from CMake, and requires a 3rd party dependency to work (Boost, POCO, TBB, etc). It's meant to support background loading, although in my opinion (I'm dark_sylinc writing!) it did a very poor job and thus I do not recommend it. However it has been left in our code because some users did have moderate success with it, and since it was not getting in our way, it stayed.

The "new" threading code is always enabled and uses system synchronization primitives directly. You don't need to toggle anything on CMake. This code scales much better and is used to update the scene graph in parallel, AABB calculations, frustum culling, selecting LOD, culling lights, and updating v2 skeleton animations.
You tell Ogre how many worker threads we will create, which gives you a lot of control on how many threads Ogre occupies, via Root::createSceneManager (note: you must create at least one worker thread). The worker threads are created per SceneManager (i.e. if you create 2 SceneManagers with 4 threads each, Ogre will create 8 worker threads. Note that it is very likely at the moment that while the first 4 threads work, the other 4 threads will be sleeping because we still update SceneManagers serially).
The code you're referring to is the "old" threading code I do not recommend, and thus there is little interest in adding more features to it.
0 x

longer
Kobold
Posts: 28
Joined: Tue Aug 19, 2014 10:46 am

Re: Is it possible thread support pthread and std::thread.

Post by longer » Wed Jul 20, 2016 4:08 am

Thanks.I'am working at version 1.9,because i need GLES2 support.It's perfect at 2.x.I hope 2.x will soon support at GLES2 GLES3.Waiting the good news!
0 x

longer
Kobold
Posts: 28
Joined: Tue Aug 19, 2014 10:46 am

Re: Is it possible thread support pthread and std::thread.

Post by longer » Fri Apr 07, 2017 1:58 am

I find the std thread support at 2.1 10535,thanks.
0 x

Post Reply