aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYotam Barnoy2010-08-03 12:29:08 +0000
committerYotam Barnoy2010-08-03 12:29:08 +0000
commit3b4b00cf5099e3720ae93bff17c7778389b5ff62 (patch)
tree930ff16da276cc4d0b58860841ed7054880f33d3
parentbcd6dd26278a2c29209ac1505c655e846f01daf9 (diff)
downloadscummvm-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.cpp45
-rw-r--r--backends/platform/psp/audio.h10
-rw-r--r--backends/platform/psp/display_manager.cpp30
-rw-r--r--backends/platform/psp/display_manager.h12
-rw-r--r--backends/platform/psp/thread.cpp45
-rw-r--r--backends/platform/psp/thread.h20
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,