support for unmanaged threads (e.g. started from python)

metadata
Wenzel Jakob 2011-12-09 16:28:14 -05:00
parent d0795bc2a2
commit e0a7438495
3 changed files with 41 additions and 13 deletions

View File

@ -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

View File

@ -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

View File

@ -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")