support for unmanaged threads (e.g. started from python)
parent
d0795bc2a2
commit
e0a7438495
|
@ -153,6 +153,15 @@ public:
|
||||||
/// Initialize Mitsuba's threading system for simultaneous use of OpenMP
|
/// Initialize Mitsuba's threading system for simultaneous use of OpenMP
|
||||||
static void initializeOpenMP(size_t threadCount);
|
static void initializeOpenMP(size_t threadCount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Register an unmanaged thread with Mitsuba (i.e. one that
|
||||||
|
* doesn't derive from \c mitsuba::Thread)
|
||||||
|
*
|
||||||
|
* Should be called from the thread in question. The function returns
|
||||||
|
* a Mitsuba handle to the thread
|
||||||
|
*/
|
||||||
|
static Thread *registerUnmanagedThread(const std::string &name);
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
protected:
|
protected:
|
||||||
/// Virtual destructor
|
/// Virtual destructor
|
||||||
|
|
|
@ -82,18 +82,18 @@ protected:
|
||||||
virtual ~MainThread() { }
|
virtual ~MainThread() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpenMPThread : public Thread {
|
class UnmanagedThread : public Thread {
|
||||||
public:
|
public:
|
||||||
OpenMPThread(int threadIdx)
|
UnmanagedThread(const std::string &name)
|
||||||
: Thread(formatString("omp%i", threadIdx)) { }
|
: Thread(name) { }
|
||||||
|
|
||||||
virtual void run() {
|
virtual void run() {
|
||||||
Log(EError, "The OpenMP thread is already running!");
|
Log(EError, "The unmanaged thread is already running!");
|
||||||
}
|
}
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
protected:
|
protected:
|
||||||
virtual ~OpenMPThread() { }
|
virtual ~UnmanagedThread() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -331,12 +331,28 @@ void Thread::staticInitialization() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<OpenMPThread *> __ompThreads;
|
static std::vector<Thread *> __unmanagedThreads;
|
||||||
|
|
||||||
|
Thread *Thread::registerUnmanagedThread(const std::string &name) {
|
||||||
|
Thread *thread = getThread();
|
||||||
|
if (!thread) {
|
||||||
|
thread = new UnmanagedThread(name);
|
||||||
|
thread->m_running = false;
|
||||||
|
thread->m_thread = pthread_self();
|
||||||
|
thread->m_joinMutex = new Mutex();
|
||||||
|
thread->m_joined = false;
|
||||||
|
thread->incRef();
|
||||||
|
m_self->set(thread);
|
||||||
|
#pragma omp critical
|
||||||
|
__unmanagedThreads.push_back((UnmanagedThread *) thread);
|
||||||
|
}
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
void Thread::staticShutdown() {
|
void Thread::staticShutdown() {
|
||||||
for (size_t i=0; i<__ompThreads.size(); ++i)
|
for (size_t i=0; i<__unmanagedThreads.size(); ++i)
|
||||||
__ompThreads[i]->decRef();
|
__unmanagedThreads[i]->decRef();
|
||||||
__ompThreads.clear();
|
__unmanagedThreads.clear();
|
||||||
getThread()->m_running = false;
|
getThread()->m_running = false;
|
||||||
m_self->set(NULL);
|
m_self->set(NULL);
|
||||||
delete m_self;
|
delete m_self;
|
||||||
|
@ -385,7 +401,8 @@ void Thread::initializeOpenMP(size_t threadCount) {
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
#pragma omp critical
|
#pragma omp critical
|
||||||
{
|
{
|
||||||
thread = new OpenMPThread(counter);
|
thread = new UnmanagedThread(
|
||||||
|
formatString("omp%i", counter));
|
||||||
#if MTS_BROKEN_OPENMP == 1
|
#if MTS_BROKEN_OPENMP == 1
|
||||||
__threadID.set(counter);
|
__threadID.set(counter);
|
||||||
#endif
|
#endif
|
||||||
|
@ -400,7 +417,7 @@ void Thread::initializeOpenMP(size_t threadCount) {
|
||||||
thread->incRef();
|
thread->incRef();
|
||||||
m_self->set(thread);
|
m_self->set(thread);
|
||||||
#pragma omp critical
|
#pragma omp critical
|
||||||
__ompThreads.push_back((OpenMPThread *) thread);
|
__unmanagedThreads.push_back((UnmanagedThread *) thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,5 +429,5 @@ Thread::~Thread() {
|
||||||
|
|
||||||
MTS_IMPLEMENT_CLASS(Thread, true, Object)
|
MTS_IMPLEMENT_CLASS(Thread, true, Object)
|
||||||
MTS_IMPLEMENT_CLASS(MainThread, false, Thread)
|
MTS_IMPLEMENT_CLASS(MainThread, false, Thread)
|
||||||
MTS_IMPLEMENT_CLASS(OpenMPThread, false, Thread)
|
MTS_IMPLEMENT_CLASS(UnmanagedThread, false, Thread)
|
||||||
MTS_NAMESPACE_END
|
MTS_NAMESPACE_END
|
||||||
|
|
|
@ -485,12 +485,14 @@ void export_core() {
|
||||||
.def("getFileResolver", &Thread::getFileResolver, BP_RETURN_VALUE)
|
.def("getFileResolver", &Thread::getFileResolver, BP_RETURN_VALUE)
|
||||||
.def("getThread", &Thread::getThread, BP_RETURN_VALUE)
|
.def("getThread", &Thread::getThread, BP_RETURN_VALUE)
|
||||||
.def("isRunning", &Thread::isRunning)
|
.def("isRunning", &Thread::isRunning)
|
||||||
|
.def("registerUnmanagedThread", &Thread::registerUnmanagedThread, BP_RETURN_VALUE)
|
||||||
.def("sleep", &Thread::sleep)
|
.def("sleep", &Thread::sleep)
|
||||||
.def("detach", &Thread::detach)
|
.def("detach", &Thread::detach)
|
||||||
.def("join", &Thread::join)
|
.def("join", &Thread::join)
|
||||||
.def("start", &Thread::start)
|
.def("start", &Thread::start)
|
||||||
.staticmethod("sleep")
|
.staticmethod("sleep")
|
||||||
.staticmethod("getThread");
|
.staticmethod("getThread")
|
||||||
|
.staticmethod("registerUnmanagedThread");
|
||||||
|
|
||||||
BP_SETSCOPE(Thread_class);
|
BP_SETSCOPE(Thread_class);
|
||||||
bp::enum_<Thread::EThreadPriority>("EThreadPriority")
|
bp::enum_<Thread::EThreadPriority>("EThreadPriority")
|
||||||
|
|
Loading…
Reference in New Issue