From 9901329cafe913111a2525c2f8cfac073494e954 Mon Sep 17 00:00:00 2001 From: "wrenczes@gmail.com" Date: Wed, 2 Mar 2011 08:14:47 +0000 Subject: [PATCH] Moved Threading.h into JGE so that it can be used at that level. --- JGE/JGE.vcxproj | 1 + JGE/include/Threading.h | 208 ++++++++++++++++++++++++++ projects/mtg/template.vcxproj | 1 - projects/mtg/template.vcxproj.filters | 3 - 4 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 JGE/include/Threading.h diff --git a/JGE/JGE.vcxproj b/JGE/JGE.vcxproj index 5131f1c71..b2570a2e6 100644 --- a/JGE/JGE.vcxproj +++ b/JGE/JGE.vcxproj @@ -369,6 +369,7 @@ + diff --git a/JGE/include/Threading.h b/JGE/include/Threading.h new file mode 100644 index 000000000..24d2b5a0e --- /dev/null +++ b/JGE/include/Threading.h @@ -0,0 +1,208 @@ +#ifndef THREADING_H +#define THREADING_H + +#if defined (WIN32) || defined (LINUX) +#include +#include +#include +#else +#include + +#include "pspthreadman.h" + +#include "DebugRoutines.h" +#include "JLogger.h" + +namespace boost +{ + /** + ** PSP specific variant of a boost mutex & scoped_lock + */ + class mutex + { + public: + struct scoped_lock + { + scoped_lock(mutex& inMutex) : mID(inMutex.mID) + { + int result = sceKernelWaitSema(mID, 1, 0); + if (result < 0) + { + LOG("Semaphore error on lock acquire, mutex id: "); + LOG((char*)mID); + } + } + + ~scoped_lock() + { + int result = sceKernelSignalSema(mID, 1); + if (result < 0) + { + LOG("Semaphore error on lock release, mutex id: "); + LOG((char*)mID); + } + } + + int mID; + }; + + mutex() + { + mID = sceKernelCreateSema("Unnamed", 0, 1, 1, 0); + } + + ~mutex() + { + sceKernelDeleteSema(mID); + } + + int mID; + }; + + /** + ** Emulating boost::thread configuration glue, with some shortcuts + ** This detail namespace is a distillation of boost's thread.hpp, thread_data.hpp. + */ + namespace detail + { + struct thread_data_base + { + thread_data_base() + { + } + + virtual ~thread_data_base() + { + } + + virtual void run() = 0; + }; + + typedef boost::shared_ptr thread_data_ptr; + + template + class thread_data : public detail::thread_data_base + { + public: + thread_data(F f_) : f(f_) + { + } + + void run() + { + f(); + } + + private: + F f; + + void operator=(thread_data&); + thread_data(thread_data&); + }; + + } //namespace detail + + + /** + ** A simplistic implementation of boost::thread, using pspsdk calls for the thread invocation. + ** + ** The intent of its usage is this form only: + ** mWorkerThread = boost::thread(ThreadProc, this); + ** where ThreadProc is a static member function of the 'this' class,eg: + ** static void FOO::ThreadProc(void* inParam) + ** { + ** FOO* instance = reinterpret_cast(inParam); + ** // now you have class instance data available... + ** } + ** + ** Any other variant of a thread proc with more than one param is unimplemented. + */ + class thread + { + /* + ** Helper class for sceKernelStartThread, which passes args by value, not by reference + ** We use this struct to wrap any pointers that we want to pass to the worker thread. + */ + struct CallbackData + { + CallbackData(detail::thread_data_ptr inThreadInfo) + : mThreadInfo(inThreadInfo) + { + } + + detail::thread_data_ptr mThreadInfo; + }; + + public: + + thread() + { + } + + template + thread(F f, A1 a1) : mThreadInfo(make_thread_info(boost::bind(boost::type(), f, a1))) + { + LOG("Calling bind on threadproc func"); + CallbackData callbackData(mThreadInfo); + + LOG("Creating SCE Thread"); + mThreadProcID = sceKernelCreateThread( typeid(a1).name(), thread::ThreadProc, 0x12, 0x20000, PSP_THREAD_ATTR_USER, NULL); + if (mThreadProcID > 0) + { + sceKernelStartThread(mThreadProcID, sizeof(CallbackData), &callbackData); + } + } + + ~thread() + { + } + + void join() + { + sceKernelTerminateDeleteThread(mThreadProcID); + } + + private: + + static int ThreadProc(SceSize args, void *inParam) + { + LOG("Entering thread::ThreadProc"); + CallbackData* callbackData = reinterpret_cast(inParam); + if (callbackData) + { + callbackData->mThreadInfo->run(); + } + + return 0; + } + + template + static inline detail::thread_data_ptr make_thread_info(F f) + { + return detail::thread_data_ptr(new detail::thread_data(f)); + } + + detail::thread_data_ptr mThreadInfo; + SceUID mThreadProcID; + }; + + namespace posix_time + { + typedef unsigned int milliseconds; + } + + /** + ** boost's platform neutral sleep call. + */ + namespace this_thread + { + inline void sleep(boost::posix_time::milliseconds const& time) + { + sceKernelDelayThread(time * 1000); + } + } +} + +#endif + +#endif // THREADING_H diff --git a/projects/mtg/template.vcxproj b/projects/mtg/template.vcxproj index cb5cfa792..f004b7a4d 100644 --- a/projects/mtg/template.vcxproj +++ b/projects/mtg/template.vcxproj @@ -521,7 +521,6 @@ - diff --git a/projects/mtg/template.vcxproj.filters b/projects/mtg/template.vcxproj.filters index ed0f6449c..4ef81348f 100644 --- a/projects/mtg/template.vcxproj.filters +++ b/projects/mtg/template.vcxproj.filters @@ -618,9 +618,6 @@ inc - - inc -