Merge changes from The Witness.
This commit is contained in:
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
Reference in New Issue
Block a user