diff options
author | Yotam Barnoy | 2010-08-03 12:29:08 +0000 |
---|---|---|
committer | Yotam Barnoy | 2010-08-03 12:29:08 +0000 |
commit | 3b4b00cf5099e3720ae93bff17c7778389b5ff62 (patch) | |
tree | 930ff16da276cc4d0b58860841ed7054880f33d3 | |
parent | bcd6dd26278a2c29209ac1505c655e846f01daf9 (diff) | |
download | scummvm-rg350-3b4b00cf5099e3720ae93bff17c7778389b5ff62.tar.gz scummvm-rg350-3b4b00cf5099e3720ae93bff17c7778389b5ff62.tar.bz2 scummvm-rg350-3b4b00cf5099e3720ae93bff17c7778389b5ff62.zip |
PSP: Factored out thread creation routines into PspThreadable class.
This should aid in further optimizations.
svn-id: r51685
-rw-r--r-- | backends/platform/psp/audio.cpp | 45 | ||||
-rw-r--r-- | backends/platform/psp/audio.h | 10 | ||||
-rw-r--r-- | backends/platform/psp/display_manager.cpp | 30 | ||||
-rw-r--r-- | backends/platform/psp/display_manager.h | 12 | ||||
-rw-r--r-- | backends/platform/psp/thread.cpp | 45 | ||||
-rw-r--r-- | backends/platform/psp/thread.h | 20 |
6 files changed, 89 insertions, 73 deletions
diff --git a/backends/platform/psp/audio.cpp b/backends/platform/psp/audio.cpp index bf1fb9ab41..e540733162 100644 --- a/backends/platform/psp/audio.cpp +++ b/backends/platform/psp/audio.cpp @@ -28,7 +28,6 @@ #include "common/scummsys.h" #include "backends/platform/psp/audio.h" -#include "backends/platform/psp/thread.h" //#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */ //#define __PSP_DEBUG_PRINT__ /* For debug printouts */ @@ -85,43 +84,13 @@ bool PspAudio::open(uint32 freq, uint32 numOfChannels, uint32 numOfSamples, call _init = true; _paused = true; // start in paused mode - createThread(); + threadCreateAndStart("audioThread", PRIORITY_AUDIO_THREAD, STACK_AUDIO_THREAD); // start the consumer thread return true; } -bool PspAudio::createThread() { - DEBUG_ENTER_FUNC(); - int threadId = sceKernelCreateThread("audioThread", thread, PRIORITY_AUDIO_THREAD, STACK_AUDIO_THREAD, THREAD_ATTR_USER, 0); - - if (threadId < 0) { // error - PSP_ERROR("failed to create audio thread. Error code %d\n", threadId); - return false; - } - - PspAudio *_this = this; // trick to get into context when the thread starts - - if (sceKernelStartThread(threadId, sizeof(uint32 *), &_this) < 0) { - PSP_ERROR("failed to start thread %d\n", threadId); - return false; - } - - PSP_DEBUG_PRINT("created audio thread[%x]\n", threadId); - - return true; -} - -// Static function to be called upon thread startup. Will call a non-static function -int PspAudio::thread(SceSize, void *__this) { - DEBUG_ENTER_FUNC(); - PspAudio *_this = *(PspAudio **)__this; // get our this for the context - - _this->audioThread(); - return 0; -}; - // The real thread function -void PspAudio::audioThread() { +void PspAudio::threadFunction() { assert(_callback); PSP_DEBUG_PRINT_FUNC("audio thread started\n"); @@ -129,15 +98,15 @@ void PspAudio::audioThread() { if (_paused) PSP_DEBUG_PRINT("audio thread paused\n"); while (_paused) { // delay until we stop pausing - sceKernelDelayThread(100000); // 100ms + PspThread::delayMicros(100000); // 100ms if (!_paused) PSP_DEBUG_PRINT("audio thread unpaused\n"); } - PSP_DEBUG_PRINT("remaining samples[%d]\n", remainingSamples); + PSP_DEBUG_PRINT("remaining samples[%d]\n", _remainingSamples); PSP_DEBUG_PRINT("filling buffer[%d]\n", _bufferToFill); - _callback(_userData, _buffers[_bufferToFill], _bufferSize); // ask mixer to fill in + _callback(_userData, _buffers[_bufferToFill], _bufferSize); // ask mixer to fill in data nextBuffer(_bufferToFill); PSP_DEBUG_PRINT("playing buffer[%d].\n", _bufferToPlay); @@ -151,7 +120,7 @@ void PspAudio::audioThread() { PSP_DEBUG_PRINT("audio thread exiting. ****************************\n"); } -// Much faster than using % +// Much faster than using %, especially with conditional moves (MIPS) inline void PspAudio::nextBuffer(int &bufferIdx) { DEBUG_ENTER_FUNC(); bufferIdx++; @@ -176,6 +145,6 @@ inline bool PspAudio::playBuffer() { } void PspAudio::close() { - PSP_DEBUG_PRINT("close had been called ***************\n"); + PSP_DEBUG_PRINT("close has been called ***************\n"); _init = false; } diff --git a/backends/platform/psp/audio.h b/backends/platform/psp/audio.h index 603f8f6bfc..eeba598fed 100644 --- a/backends/platform/psp/audio.h +++ b/backends/platform/psp/audio.h @@ -26,13 +26,15 @@ #ifndef PSP_AUDIO_H #define PSP_AUDIO_H -class PspAudio { +#include "backends/platform/psp/thread.h" + +class PspAudio : public PspThreadable { public: enum { NUM_BUFFERS = 2, FREQUENCY = 44100 /* only frequency we allow */ }; - typedef void (* callbackFunc)(void *userData, byte *samples, int len); + typedef void (* callbackFunc)(void *userData, byte *samples, int len); // audio callback to call PspAudio() : _pspChannel(0), _numOfChannels(0), _numOfSamples(0), _callback(0), _bufferToPlay(0), _bufferToFill(0), @@ -43,14 +45,12 @@ public: ~PspAudio() { close(); } bool playBuffer(); void nextBuffer(int &bufferIdx); - static int thread(SceSize, void *); - void audioThread(); bool open(uint32 freq, uint32 numOfChannels, uint32 numOfSamples, callbackFunc callback, void *userData); - bool createThread(); void close(); uint32 getFrequency() { return FREQUENCY; } void pause() { _paused = true; } void unpause() { _paused = false; } + virtual void threadFunction(); // actual audio thread private: int _pspChannel; // chosen hardware output channel diff --git a/backends/platform/psp/display_manager.cpp b/backends/platform/psp/display_manager.cpp index a9f33f6091..5037543f12 100644 --- a/backends/platform/psp/display_manager.cpp +++ b/backends/platform/psp/display_manager.cpp @@ -34,7 +34,6 @@ #include "backends/platform/psp/default_display_client.h" #include "backends/platform/psp/cursor.h" #include "backends/platform/psp/pspkeyboard.h" -#include "backends/platform/psp/thread.h" #define USE_DISPLAY_CALLBACK // to use callback for finishing the render #include "backends/platform/psp/display_manager.h" @@ -65,37 +64,24 @@ const OSystem::GraphicsMode DisplayManager::_supportedModes[] = { void MasterGuRenderer::setupCallbackThread() { DEBUG_ENTER_FUNC(); - int thid = sceKernelCreateThread("displayCbThread", guCallbackThread, PRIORITY_DISPLAY_THREAD, STACK_DISPLAY_THREAD, THREAD_ATTR_USER, 0); - PSP_DEBUG_PRINT("Display CB thread id is %x\n", thid); - - // We want to pass the pointer to this, but we'll have to take address of this so use a little trick - MasterGuRenderer *_this = this; - - if (thid >= 0) { - sceKernelStartThread(thid, sizeof(uint32 *), &_this); - } else - PSP_ERROR("failed to create display callback thread\n"); + // start the thread that updates the display + threadCreateAndStart("DisplayCbThread", PRIORITY_DISPLAY_THREAD, STACK_DISPLAY_THREAD); } -// thread that reacts to the callback -int MasterGuRenderer::guCallbackThread(SceSize, void *__this) { +// this function gets called by PspThread when starting the new thread +void MasterGuRenderer::threadFunction() { DEBUG_ENTER_FUNC(); - // Dereferenced the copied value which was this - MasterGuRenderer *_this = *(MasterGuRenderer **)__this; - // Create the callback. It should always get the pointer to MasterGuRenderer - _this->_callbackId = sceKernelCreateCallback("Display Callback", guCallback, _this); - if (_this->_callbackId < 0) { - PSP_ERROR("failed to create display callback\n"); - return -1; + _callbackId = sceKernelCreateCallback("Display Callback", guCallback, this); + if (_callbackId < 0) { + PSP_ERROR("failed to create display callback\n"); } PSP_DEBUG_PRINT("created callback. Going to sleep\n"); - sceKernelSleepThreadCB(); // sleep until we get a callback - return 0; + sceKernelSleepThreadCB(); // sleep until we get a callback } // This callback is called when the render is finished. It swaps the buffers diff --git a/backends/platform/psp/display_manager.h b/backends/platform/psp/display_manager.h index dbbdf2022c..1f7320902c 100644 --- a/backends/platform/psp/display_manager.h +++ b/backends/platform/psp/display_manager.h @@ -26,10 +26,12 @@ #ifndef PSP_DISPLAY_MAN_H #define PSP_DISPLAY_MAN_H +#include "backends/platform/psp/thread.h" + /** * Class used only by DisplayManager to start/stop GU rendering */ -class MasterGuRenderer { +class MasterGuRenderer : public PspThreadable { public: MasterGuRenderer() : _lastRenderTime(0), _renderFinished(true), _callbackId(-1) {} void guInit(); @@ -37,15 +39,15 @@ public: void guPostRender(); void guShutDown(); bool isRenderFinished() { return _renderFinished; } - void setupCallbackThread(); + void setupCallbackThread(); private: + virtual void threadFunction(); // for the display callback thread static uint32 _displayList[]; uint32 _lastRenderTime; // For measuring rendering time void guProgramDisplayBufferSizes(); - static int guCallbackThread(SceSize, void *); // for the graphics callbacks - static int guCallback(int, int, void *__this); + static int guCallback(int, int, void *__this); // for the display callback bool _renderFinished; // for sync with render callback - int _callbackId; // to keep track of render callback + int _callbackId; // to keep track of render callback }; class Screen; diff --git a/backends/platform/psp/thread.cpp b/backends/platform/psp/thread.cpp index c19ff5f9e3..916b1e553b 100644 --- a/backends/platform/psp/thread.cpp +++ b/backends/platform/psp/thread.cpp @@ -28,7 +28,50 @@ #include "backends/platform/psp/thread.h" #include "backends/platform/psp/trace.h" -// Class PspThread -------------------------------------------------- +// Class PspThreadable -------------------------------------------------- +// Inherit this to create C++ threads easily + +bool PspThreadable::threadCreateAndStart(const char *threadName, int priority, int stackSize, bool useVfpu /*= false*/) { + DEBUG_ENTER_FUNC(); + + if (_threadId != -1) { + PSP_ERROR("thread already created!\n"); + return false; + } + + _threadId = sceKernelCreateThread(threadName, __threadCallback, priority, stackSize, THREAD_ATTR_USER, 0); // add VFPU support + + if (_threadId < 0) { + PSP_ERROR("failed to create %s thread. Error code %d\n", threadName, _threadId); + return false; + } + + // We want to pass the pointer to this, but we'll have to take address of this so use a little trick + PspThreadable *_this = this; + + if (sceKernelStartThread(_threadId, sizeof(uint32 *), &_this) < 0) { + PSP_ERROR("failed to start %s thread id[%d]\n", threadName, _threadId); + return false; + } + + PSP_DEBUG_PRINT("Started %s thread with id[%x]\n", threadName, _threadId); + + return true; +} + +// Callback function to be called by PSP kernel +int PspThreadable::__threadCallback(SceSize, void *__this) { + DEBUG_ENTER_FUNC(); + + PspThreadable *_this = *(PspThreadable **)__this; // Dereference the copied value which was 'this' + + _this->threadFunction(); // call the virtual function + + return 0; +} + +// PspThread class +// Utilities to access general thread functions void PspThread::delayMillis(uint32 ms) { sceKernelDelayThread(ms * 1000); diff --git a/backends/platform/psp/thread.h b/backends/platform/psp/thread.h index 27d53903d6..de1c10a2aa 100644 --- a/backends/platform/psp/thread.h +++ b/backends/platform/psp/thread.h @@ -26,11 +26,26 @@ #ifndef PSP_THREAD_H #define PSP_THREAD_H +#include <pspthreadman.h> #include "common/scummsys.h" +// class to inherit for creating threads +class PspThreadable { +protected: + int _threadId; + virtual void threadFunction() = 0; // this function will be called when the thread starts +public: + PspThreadable() : _threadId(-1) {} // constructor + virtual ~PspThreadable() {} // destructor + static int __threadCallback(SceSize, void *__this); // used to get called by sceKernelStartThread() Don't override + bool threadCreateAndStart(const char *threadName, int priority, int stackSize, bool useVfpu = false); +}; + +// class for thread utils class PspThread { -public: - static void delayMillis(uint32 ms); +public: + // static functions + static void delayMillis(uint32 ms); // delay the current thread static void delayMicros(uint32 us); }; @@ -85,6 +100,7 @@ enum ThreadPriority { }; enum StackSizes { + STACK_DEFAULT = 4 * 1024, STACK_AUDIO_THREAD = 16 * 1024, STACK_TIMER_THREAD = 32 * 1024, STACK_DISPLAY_THREAD = 2 * 1024, |