Merge changes from The Witness.

This commit is contained in:
castano
2012-07-20 16:19:03 +00:00
parent fea97461c5
commit 3b4fcd0369
36 changed files with 1073 additions and 178 deletions

View File

@ -34,25 +34,33 @@ void Event::wait() {
#elif NV_OS_UNIX
// @@ TODO
#pragma NV_MESSAGE("Implement event using pthreads!")
struct Event::Private {
pthread_cond_t pt_cond;
pthread_mutex_t pt_mutex;
};
Event::Event() : m(new Private) {
// pthread equivalent of auto-reset event
pthread_cond_init(&m->pt_cond, NULL);
pthread_mutex_init(&m->pt_mutex, NULL);
}
Event::~Event() {
pthread_cond_destroy(&m->pt_cond);
pthread_mutex_destroy(&m->pt_mutex);
}
void Event::post() {
pthread_cond_signal(&m->pt_cond);
}
void Event::wait() {
pthread_cond_wait(&m->pt_cond, &m->pt_mutex);
}
#endif
#endif // NV_OS_UNIX
/*static*/ void Event::post(Event * events, uint count) {

View File

@ -27,7 +27,7 @@ struct Thread::Private
#if NV_OS_WIN32
unsigned long __stdcall threadFunc(void * arg) {
Thread * thread = (Thread *)arg;
Thread::Private * thread = (Thread::Private *)arg;
thread->func(thread->arg);
return 0;
}
@ -35,7 +35,7 @@ unsigned long __stdcall threadFunc(void * arg) {
#elif NV_OS_UNIX
extern "C" void * threadFunc(void * arg) {
Thread * thread = (Thread *)arg;
Thread::Private * thread = (Thread::Private *)arg;
thread->func(thread->arg);
pthread_exit(0);
}
@ -55,15 +55,15 @@ Thread::~Thread()
void Thread::start(ThreadFunc * func, void * arg)
{
this->func = func;
this->arg = arg;
p->func = func;
p->arg = arg;
#if NV_OS_WIN32
p->thread = CreateThread(NULL, 0, threadFunc, this, 0, NULL);
//p->thread = (HANDLE)_beginthreadex (0, 0, threadFunc, this, 0, NULL); // @@ So that we can call CRT functions...
p->thread = CreateThread(NULL, 0, threadFunc, p.ptr(), 0, NULL);
//p->thread = (HANDLE)_beginthreadex (0, 0, threadFunc, p.ptr(), 0, NULL); // @@ So that we can call CRT functions...
nvDebugCheck(p->thread != NULL);
#elif NV_OS_UNIX
int result = pthread_create(&p->thread, NULL, threadFunc, this);
int result = pthread_create(&p->thread, NULL, threadFunc, p.ptr());
nvDebugCheck(result == 0);
#endif
}

View File

@ -6,7 +6,7 @@
#include "nvthread.h"
#include "nvcore/Ptr.h"
#include "nvcore/Ptr.h" // AutoPtr
namespace nv
{
@ -30,15 +30,8 @@ namespace nv
static void wait(Thread * threads, uint count);
private:
struct Private;
AutoPtr<Private> p;
public: // @@ Why public? Also in private?!
ThreadFunc * func;
void * arg;
};
} // nv namespace

View File

@ -79,6 +79,8 @@ ThreadPool::ThreadPool()
startEvents = new Event[workerCount];
finishEvents = new Event[workerCount];
nvCompilerWriteBarrier(); // @@ Use a memory fence?
for (uint i = 0; i < workerCount; i++) {
workers[i].start(workerFunc, (void *)i);
}
@ -110,8 +112,6 @@ void ThreadPool::start(ThreadFunc * func, void * arg)
allIdle = false;
nvCompilerWriteBarrier();
// Resume threads.
Event::post(startEvents, workerCount);
}

View File

@ -9,6 +9,12 @@
#include "Event.h"
#include "Thread.h"
// The thread pool creates one worker thread for each physical core.
// The threads are idle waiting for their start events so that they do not consume any resources while inactive.
// The thread pool runs the same function in all worker threads, the idea is to use this as the foundation of a custom task scheduler.
// When the thread pool starts, the main thread continues running, but the common use case is to inmmediately wait of the termination events of the worker threads.
// @@ The start and wait methods could probably be merged.
namespace nv {
class Thread;

View File

@ -9,14 +9,13 @@
#elif NV_OS_UNIX
#include <sys/types.h>
#include <sys/sysctl.h>
#include <unistd.h>
#elif NV_OS_DARWIN
#import <stdio.h>
#import <string.h>
#import <mach/mach_host.h>
#import <sys/sysctl.h>
#include <CoreFoundation/CoreFoundation.h>
//#include <CoreFoundation/CoreFoundation.h>
#include <assert.h>
#include <errno.h>