Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None
diff --git a/util/thread.cpp b/util/thread.cpp
index 982e7aab..f4bfd1d8 100644
--- a/util/thread.cpp
+++ b/util/thread.cpp
@@ -1,141 +1,173 @@
#include "thread.h"
namespace Util{
namespace Thread{
#ifdef USE_SDL
void initializeLock(Lock * lock){
*lock = SDL_CreateMutex();
}
int acquireLock(Lock * lock){
return SDL_LockMutex(*lock);
}
int releaseLock(Lock * lock){
return SDL_UnlockMutex(*lock);
}
void destroyLock(Lock * lock){
SDL_DestroyMutex(*lock);
}
+void initializeSemaphore(Semaphore * semaphore, unsigned int value){
+ *semaphore = SDL_CreateSemaphore(value);
+}
+
+void destroySemaphore(Semaphore * semaphore){
+ SDL_DestroySemaphore(*semaphore);
+}
+
+void semaphoreDecrease(Semaphore * semaphore){
+ SDL_SemWait(*semaphore);
+}
+
+void semaphoreIncrease(Semaphore * semaphore){
+ SDL_SemPost(*semaphore);
+}
+
bool createThread(Id * thread, void * attributes, ThreadFunction function, void * arg){
*thread = SDL_CreateThread(function, arg);
return *thread != NULL;
}
void joinThread(Id thread){
SDL_WaitThread(thread, NULL);
}
void cancelThread(Id thread){
SDL_KillThread(thread);
}
#else
void initializeLock(Lock * lock){
pthread_mutex_init(lock, NULL);
}
int acquireLock(Lock * lock){
return pthread_mutex_lock(lock);
}
int releaseLock(Lock * lock){
return pthread_mutex_unlock(lock);
}
+void initializeSemaphore(Semaphore * semaphore, unsigned int value){
+ sem_init(semaphore, 0, value);
+}
+
+void destroySemaphore(Semaphore * semaphore){
+ /* nothing */
+}
+
+void semaphoreDecrease(Semaphore * semaphore){
+ sem_wait(semaphore);
+}
+
+void semaphoreIncrease(Semaphore * semaphore){
+ sem_post(semaphore);
+}
+
bool createThread(Id * thread, void * attributes, ThreadFunction function, void * arg){
return pthread_create(thread, (pthread_attr_t*) attributes, function, arg) == 0;
}
void joinThread(Id thread){
pthread_join(thread, NULL);
}
void cancelThread(Id thread){
/* FIXME: cancel is not implemented for libogc, find another way.
* thread suspend/resume is there, though.
*/
#if !defined(WII)
pthread_cancel(thread);
#endif
}
void destroyLock(Lock * lock){
/* nothing */
}
#endif
}
WaitThread::WaitThread():
done(false){
Thread::initializeLock(&doneLock);
}
WaitThread::WaitThread(Thread::ThreadFunction thread, void * arg){
Thread::initializeLock(&doneLock);
start(thread, arg);
}
static void * do_thread(void * arg){
WaitThread * thread = (WaitThread *) arg;
thread->doRun();
return NULL;
}
void WaitThread::doRun(){
this->function(this->arg);
Thread::acquireLock(&doneLock);
this->done = true;
Thread::releaseLock(&doneLock);
}
void WaitThread::start(Thread::ThreadFunction thread, void * arg){
done = false;
this->arg = arg;
this->function = thread;
Thread::createThread(&this->thread, NULL, (Thread::ThreadFunction) do_thread, this);
}
bool WaitThread::isRunning(){
Thread::acquireLock(&doneLock);
bool what = done;
Thread::releaseLock(&doneLock);
return what;
}
void WaitThread::kill(){
Thread::cancelThread(thread);
Thread::joinThread(thread);
}
WaitThread::~WaitThread(){
/* FIXME: Should we join the thread? */
/* pthread_join(thread); */
}
ThreadBoolean::ThreadBoolean(volatile bool & what, Thread::Lock & lock):
what(what),
lock(lock){
}
bool ThreadBoolean::get(){
Thread::acquireLock(&lock);
bool b = what;
Thread::releaseLock(&lock);
return b;
}
void ThreadBoolean::set(bool value){
Thread::acquireLock(&lock);
what = value;
Thread::releaseLock(&lock);
}
}
diff --git a/util/thread.h b/util/thread.h
index 06d73932..f648b8e3 100644
--- a/util/thread.h
+++ b/util/thread.h
@@ -1,113 +1,135 @@
#ifndef _paintown_thread_h
#define _paintown_thread_h
#ifdef USE_SDL
#include <SDL_thread.h>
#include <SDL_mutex.h>
#else
#include <pthread.h>
+#include <semaphore.h>
#endif
+#include "exceptions/exception.h"
+
namespace Util{
/* Either uses pthreads or SDL_thread */
namespace Thread{
#ifdef USE_SDL
typedef SDL_mutex* Lock;
typedef SDL_Thread* Id;
typedef int (*ThreadFunction)(void*);
+ typedef SDL_semaphore* Semaphore;
#else
typedef pthread_mutex_t Lock;
typedef pthread_t Id;
+ typedef sem_t Semaphore;
typedef void * (*ThreadFunction)(void*);
#endif
void initializeLock(Lock * lock);
+ void initializeSemaphore(Semaphore * semaphore, unsigned int value);
+ void destroySemaphore(Semaphore * semaphore);
+ void semaphoreDecrease(Semaphore * semaphore);
+ void semaphoreIncrease(Semaphore * semaphore);
+
int acquireLock(Lock * lock);
int releaseLock(Lock * lock);
void destroyLock(Lock * lock);
bool createThread(Id * thread, void * attributes, ThreadFunction function, void * arg);
void joinThread(Id thread);
void cancelThread(Id thread);
}
class WaitThread{
public:
/* does not start a new thread yet */
WaitThread();
/* starts a thread */
WaitThread(Thread::ThreadFunction thread, void * arg);
/* starts a thread */
void start(Thread::ThreadFunction thread, void * arg);
bool isRunning();
void kill();
virtual ~WaitThread();
public:
/* actually runs the thread */
void doRun();
protected:
Thread::Lock doneLock;
Thread::Id thread;
volatile bool done;
void * arg;
Thread::ThreadFunction function;
};
/* wraps a boolean with lock/unlock while checking/setting it */
class ThreadBoolean{
public:
ThreadBoolean(volatile bool & what, Thread::Lock & lock);
bool get();
void set(bool value);
protected:
volatile bool & what;
Thread::Lock & lock;
};
template<class X>
class Future{
public:
- Future(){
+ Future():
+ thing(0){
+ /* future will increase the count */
+ Thread::initializeSemaphore(&future, 0);
}
virtual ~Future(){
+ Thread::joinThread(thread);
+ Thread::destroySemaphore(&future);
}
virtual X get(){
- Thread::joinThread(thread);
- return thing;
+ X out;
+ Thread::semaphoreDecrease(&future);
+ out = thing;
+ Thread::semaphoreIncrease(&future);
+ return out;
}
protected:
static void * runit(void * arg){
Future<X> * me = (Future<X>*) arg;
me->compute();
+ Thread::semaphoreIncrease(&me->future);
return NULL;
}
virtual void set(X x){
this->thing = x;
}
virtual void start(){
- Thread::createThread(&thread, NULL, (Thread::ThreadFunction) runit, this);
+ if (!Thread::createThread(&thread, NULL, (Thread::ThreadFunction) runit, this)){
+ throw Exception::Base(__FILE__, __LINE__);
+ }
}
virtual void compute() = 0;
X thing;
Thread::Id thread;
+ Thread::Semaphore future;
};
}
#endif

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 12:25 PM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
69023
Default Alt Text
(6 KB)

Event Timeline