mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
c569b33829
Second: A experiment. implemented parallelization in texture decoding using openmp. is most a experiment to test the performance in different os/plataforms. in my system (windows x64 amd 1055t) give a speedup in large textures, but i tested in in intel dual core and gives a slowdown. o i limited the use for large textures and cpus with more than 3 cores. please test an let me know if it improves or degrades the speed. please for linux and osx user. to enable this you will have to enable your compiler support for openmp to test this code. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7284 8ced0084-cf51-0410-be5f-012b33b47a6e
308 lines
5.0 KiB
Objective-C
308 lines
5.0 KiB
Objective-C
|
|
#ifndef STD_THREAD_H_
|
|
#define STD_THREAD_H_
|
|
|
|
#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
|
|
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
|
|
|
|
#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
|
|
// GCC 4.4 provides <thread>
|
|
#include <thread>
|
|
#else
|
|
|
|
// partial std::thread implementation for win32/pthread
|
|
|
|
#include <algorithm>
|
|
|
|
#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
|
|
#define USE_RVALUE_REFERENCES
|
|
#endif
|
|
|
|
#ifdef __APPLE__
|
|
#import <Foundation/NSAutoreleasePool.h>
|
|
#endif
|
|
|
|
#if defined(_WIN32)
|
|
// WIN32
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <Windows.h>
|
|
|
|
#if defined(_MSC_VER) && defined(_MT)
|
|
// When linking with LIBCMT (the multithreaded C library), Microsoft recommends
|
|
// using _beginthreadex instead of CreateThread.
|
|
#define USE_BEGINTHREADEX
|
|
#include <process.h>
|
|
#endif
|
|
|
|
#ifdef USE_BEGINTHREADEX
|
|
#define THREAD_ID unsigned
|
|
#define THREAD_RETURN unsigned __stdcall
|
|
#else
|
|
#define THREAD_ID DWORD
|
|
#define THREAD_RETURN DWORD WINAPI
|
|
#endif
|
|
#define THREAD_HANDLE HANDLE
|
|
|
|
#else
|
|
// PTHREAD
|
|
|
|
#include <unistd.h>
|
|
|
|
#ifndef _POSIX_THREADS
|
|
#error unsupported platform (no pthreads?)
|
|
#endif
|
|
|
|
#include <pthread.h>
|
|
|
|
#define THREAD_ID pthread_t
|
|
#define THREAD_HANDLE pthread_t
|
|
#define THREAD_RETURN void*
|
|
|
|
#endif
|
|
|
|
namespace std
|
|
{
|
|
|
|
class thread
|
|
{
|
|
public:
|
|
typedef THREAD_HANDLE native_handle_type;
|
|
|
|
class id
|
|
{
|
|
friend class thread;
|
|
public:
|
|
id() : m_thread(0) {}
|
|
id(THREAD_ID _id) : m_thread(_id) {}
|
|
|
|
bool operator==(const id& rhs) const
|
|
{
|
|
return m_thread == rhs.m_thread;
|
|
}
|
|
|
|
bool operator!=(const id& rhs) const
|
|
{
|
|
return !(*this == rhs);
|
|
}
|
|
|
|
bool operator<(const id& rhs) const
|
|
{
|
|
return m_thread < rhs.m_thread;
|
|
}
|
|
|
|
private:
|
|
THREAD_ID m_thread;
|
|
};
|
|
|
|
// no variadic template support in msvc
|
|
//template <typename C, typename... A>
|
|
//thread(C&& func, A&&... args);
|
|
|
|
template <typename C>
|
|
thread(C func)
|
|
{
|
|
StartThread(new Func<C>(func));
|
|
}
|
|
|
|
template <typename C, typename A>
|
|
thread(C func, A arg)
|
|
{
|
|
StartThread(new FuncArg<C, A>(func, arg));
|
|
}
|
|
|
|
thread() /*= default;*/ {}
|
|
|
|
#ifdef USE_RVALUE_REFERENCES
|
|
thread(const thread&) /*= delete*/;
|
|
|
|
thread(thread&& other)
|
|
{
|
|
#else
|
|
thread(const thread& t)
|
|
{
|
|
// ugly const_cast to get around lack of rvalue references
|
|
thread& other = const_cast<thread&>(t);
|
|
#endif
|
|
swap(other);
|
|
}
|
|
|
|
#ifdef USE_RVALUE_REFERENCES
|
|
thread& operator=(const thread&) /*= delete*/;
|
|
|
|
thread& operator=(thread&& other)
|
|
{
|
|
#else
|
|
thread& operator=(const thread& t)
|
|
{
|
|
// ugly const_cast to get around lack of rvalue references
|
|
thread& other = const_cast<thread&>(t);
|
|
#endif
|
|
if (joinable())
|
|
detach();
|
|
swap(other);
|
|
return *this;
|
|
}
|
|
|
|
~thread()
|
|
{
|
|
if (joinable())
|
|
detach();
|
|
}
|
|
|
|
bool joinable() const
|
|
{
|
|
return m_id != id();
|
|
}
|
|
|
|
id get_id() const
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
native_handle_type native_handle()
|
|
{
|
|
#ifdef _WIN32
|
|
return m_handle;
|
|
#else
|
|
return m_id.m_thread;
|
|
#endif
|
|
}
|
|
|
|
void join()
|
|
{
|
|
#ifdef _WIN32
|
|
WaitForSingleObject(m_handle, INFINITE);
|
|
detach();
|
|
#else
|
|
pthread_join(m_id.m_thread, NULL);
|
|
m_id = id();
|
|
#endif
|
|
}
|
|
|
|
void detach()
|
|
{
|
|
#ifdef _WIN32
|
|
CloseHandle(m_handle);
|
|
#else
|
|
pthread_detach(m_id.m_thread);
|
|
#endif
|
|
m_id = id();
|
|
}
|
|
|
|
void swap(thread& other)
|
|
{
|
|
std::swap(m_id, other.m_id);
|
|
#ifdef _WIN32
|
|
std::swap(m_handle, other.m_handle);
|
|
#endif
|
|
}
|
|
|
|
static unsigned hardware_concurrency()
|
|
{
|
|
#ifdef _WIN32
|
|
SYSTEM_INFO sysinfo;
|
|
GetSystemInfo(&sysinfo);
|
|
return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
private:
|
|
id m_id;
|
|
|
|
#ifdef _WIN32
|
|
native_handle_type m_handle;
|
|
#endif
|
|
|
|
template <typename F>
|
|
void StartThread(F* param)
|
|
{
|
|
#ifdef USE_BEGINTHREADEX
|
|
m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
|
|
#elif defined(_WIN32)
|
|
m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
|
|
#else
|
|
pthread_attr_t attr;
|
|
pthread_attr_init(&attr);
|
|
pthread_attr_setstacksize(&attr, 1024 * 1024);
|
|
if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param))
|
|
m_id = id();
|
|
#endif
|
|
}
|
|
|
|
template <typename C>
|
|
class Func
|
|
{
|
|
public:
|
|
Func(C _func) : func(_func) {}
|
|
|
|
void Run() { func(); }
|
|
|
|
private:
|
|
C const func;
|
|
};
|
|
|
|
template <typename C, typename A>
|
|
class FuncArg
|
|
{
|
|
public:
|
|
FuncArg(C _func, A _arg) : func(_func), arg(_arg) {}
|
|
|
|
void Run() { func(arg); }
|
|
|
|
private:
|
|
C const func;
|
|
A arg;
|
|
};
|
|
|
|
template <typename F>
|
|
static THREAD_RETURN RunAndDelete(void* param)
|
|
{
|
|
#ifdef __APPLE__
|
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
#endif
|
|
static_cast<F*>(param)->Run();
|
|
delete static_cast<F*>(param);
|
|
#ifdef __APPLE__
|
|
[pool release];
|
|
#endif
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
namespace this_thread
|
|
{
|
|
|
|
inline void yield()
|
|
{
|
|
#ifdef _WIN32
|
|
Sleep(0);
|
|
#else
|
|
sleep(0);
|
|
#endif
|
|
}
|
|
|
|
inline thread::id get_id()
|
|
{
|
|
#ifdef _WIN32
|
|
return GetCurrentThreadId();
|
|
#else
|
|
return pthread_self();
|
|
#endif
|
|
}
|
|
|
|
} // namespace this_thread
|
|
|
|
} // namespace std
|
|
|
|
#undef USE_RVALUE_REFERENCES
|
|
#undef USE_BEGINTHREADEX
|
|
#undef THREAD_ID
|
|
#undef THREAD_RETURN
|
|
#undef THREAD_HANDLE
|
|
|
|
#endif
|
|
#endif
|