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
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()
protected:
/// Virtual destructor

View File

@ -82,18 +82,18 @@ protected:
virtual ~MainThread() { }
};
class OpenMPThread : public Thread {
class UnmanagedThread : public Thread {
public:
OpenMPThread(int threadIdx)
: Thread(formatString("omp%i", threadIdx)) { }
UnmanagedThread(const std::string &name)
: Thread(name) { }
virtual void run() {
Log(EError, "The OpenMP thread is already running!");
Log(EError, "The unmanaged thread is already running!");
}
MTS_DECLARE_CLASS()
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() {
for (size_t i=0; i<__ompThreads.size(); ++i)
__ompThreads[i]->decRef();
__ompThreads.clear();
for (size_t i=0; i<__unmanagedThreads.size(); ++i)
__unmanagedThreads[i]->decRef();
__unmanagedThreads.clear();
getThread()->m_running = false;
m_self->set(NULL);
delete m_self;
@ -385,7 +401,8 @@ void Thread::initializeOpenMP(size_t threadCount) {
if (!thread) {
#pragma omp critical
{
thread = new OpenMPThread(counter);
thread = new UnmanagedThread(
formatString("omp%i", counter));
#if MTS_BROKEN_OPENMP == 1
__threadID.set(counter);
#endif
@ -400,7 +417,7 @@ void Thread::initializeOpenMP(size_t threadCount) {
thread->incRef();
m_self->set(thread);
#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(MainThread, false, Thread)
MTS_IMPLEMENT_CLASS(OpenMPThread, false, Thread)
MTS_IMPLEMENT_CLASS(UnmanagedThread, false, Thread)
MTS_NAMESPACE_END

View File

@ -485,12 +485,14 @@ void export_core() {
.def("getFileResolver", &Thread::getFileResolver, BP_RETURN_VALUE)
.def("getThread", &Thread::getThread, BP_RETURN_VALUE)
.def("isRunning", &Thread::isRunning)
.def("registerUnmanagedThread", &Thread::registerUnmanagedThread, BP_RETURN_VALUE)
.def("sleep", &Thread::sleep)
.def("detach", &Thread::detach)
.def("join", &Thread::join)
.def("start", &Thread::start)
.staticmethod("sleep")
.staticmethod("getThread");
.staticmethod("getThread")
.staticmethod("registerUnmanagedThread");
BP_SETSCOPE(Thread_class);
bp::enum_<Thread::EThreadPriority>("EThreadPriority")