diff options
Diffstat (limited to 'dep/src/zthread/ThreadImpl.cxx')
-rw-r--r-- | dep/src/zthread/ThreadImpl.cxx | 282 |
1 files changed, 141 insertions, 141 deletions
diff --git a/dep/src/zthread/ThreadImpl.cxx b/dep/src/zthread/ThreadImpl.cxx index c7c22883b5e..fa2fd9e36c5 100644 --- a/dep/src/zthread/ThreadImpl.cxx +++ b/dep/src/zthread/ThreadImpl.cxx @@ -34,88 +34,88 @@ namespace ZThread { TSS<ThreadImpl*> ThreadImpl::_threadMap; namespace { - + class Launcher : public Runnable { - + ThreadImpl* x; ThreadImpl* y; Task z; - + public: - + Launcher(ThreadImpl* a, ThreadImpl* b, const Task& c) : x(a), y(b), z(c) {} - - void run() { - y->dispatch(x,y,z); + + void run() { + y->dispatch(x,y,z); } - + }; - + } - ThreadImpl::ThreadImpl() + ThreadImpl::ThreadImpl() : _state(State::REFERENCE), _priority(Medium), _autoCancel(false) { - + ZTDEBUG("Reference thread created.\n"); - + } - ThreadImpl::ThreadImpl(const Task& task, bool autoCancel) + ThreadImpl::ThreadImpl(const Task& task, bool autoCancel) : _state(State::IDLE), _priority(Medium), _autoCancel(autoCancel) { - + ZTDEBUG("User thread created.\n"); start(task); } - - + + ThreadImpl::~ThreadImpl() { - + _tls.clear(); if(isActive()) { - + ZTDEBUG("You are destroying an executing thread!\n"); abort(); - + } - + ZTDEBUG("Thread destroyed.\n"); - + } - + Monitor& ThreadImpl::getMonitor() { return _monitor; } - + void ThreadImpl::cancel(bool autoCancel) { - if(!autoCancel || _autoCancel) - _monitor.cancel(); + if(!autoCancel || _autoCancel) + _monitor.cancel(); } - - bool ThreadImpl::interrupt() { - return _monitor.interrupt(); + + bool ThreadImpl::interrupt() { + return _monitor.interrupt(); } - + bool ThreadImpl::isInterrupted() { return _monitor.isInterrupted(); } - + bool ThreadImpl::isCanceled() { return _monitor.isCanceled(); } Priority ThreadImpl::getPriority() const { - return _priority; + return _priority; } - - + + bool ThreadImpl::isReference() { return _state.isReference(); } - + /** * Join the thread, blocking the caller until it is interrupted or until * the thread represented by this object exits. @@ -124,27 +124,27 @@ namespace ZThread { * joined. */ bool ThreadImpl::join(unsigned long timeout) { - + // Serial access to this ThreadImpl's state Guard<Monitor> g1(_monitor); - + // Make sure a thread is not trying to join() itself. if(ThreadOps::isCurrent(this)) throw Deadlock_Exception("Cannot join self."); - - // Reference threads can't be joined. + + // Reference threads can't be joined. if(_state.isReference()) throw InvalidOp_Exception("Can not join this thread."); - - /* - - TODO: Insert cyclic join check. - + + /* + + TODO: Insert cyclic join check. + */ - + // If the task has not completed yet, wait for completion if(!_state.isJoined()) { - + // Add the current thread to the joiner list ThreadImpl* impl = current(); _joiners.push_back(impl); @@ -153,49 +153,49 @@ namespace ZThread { { // Release this ThreadImpl's lock while the joiner sleeps - _monitor.release(); + _monitor.release(); Guard<Monitor> g3(impl->getMonitor()); - + result = impl->_monitor.wait(timeout); - + _monitor.acquire(); - + } - + // Update the joiner list List::iterator i = std::find(_joiners.begin(), _joiners.end(), impl); if(i != _joiners.end()) _joiners.erase(i); - - + + switch(result) { - + case Monitor::TIMEDOUT: return false; - + case Monitor::INTERRUPTED: throw Interrupted_Exception(); - + default: break; - + } - + } return true; - + } - + /** * Translate the priority into a pthread value, and update the thread priority. * - * This is not available on all platforms, and probably works differently - * the platforms that do support it. Pthreads does not have very portable + * This is not available on all platforms, and probably works differently + * the platforms that do support it. Pthreads does not have very portable * priority support as far I am aware. * - * If SCHED_OTHER is not supported priority values are still set but + * If SCHED_OTHER is not supported priority values are still set but * dont not actually in affect anything. * * @param prio PRIORITY value @@ -204,18 +204,18 @@ namespace ZThread { * @exception InvalidOp_Exception thrown by IDLE, JOINING or JOINED threads. */ void ThreadImpl::setPriority(Priority p) { - + Guard<Monitor> g(_monitor); - + // Only set the native priority when the thread is running if(_state.isRunning()) ThreadOps::setPriority(this, p); - + _priority = p; - + } - - + + /** * Test the state Monitor of this thread to determine if the thread * is an active thread created by zthreads. @@ -223,13 +223,13 @@ namespace ZThread { * @return bool indicating the activity of the thread. */ bool ThreadImpl::isActive() { - + Guard<Monitor> g(_monitor); return _state.isRunning(); - + } - - + + /** * Get a reference to an implmenetation that maps to the current thread. * Accomplished by checking the TLS map. This will always return a valid @@ -237,98 +237,98 @@ namespace ZThread { * * @return ThreadImpl* current implementation that maps to the * executing thread. - */ + */ ThreadImpl* ThreadImpl::current() { - + // Get the ThreadImpl previously mapped onto the executing thread. ThreadImpl* impl = _threadMap.get(); - + // Create a reference thread for any threads that have been 'discovered' // because they are not created by ZThreads. - if(impl == 0) { - - // Create a ThreadImpl to represent this thread. + if(impl == 0) { + + // Create a ThreadImpl to represent this thread. impl = new ThreadImpl(); impl->_state.setReference(); - + ThreadOps::activate(impl); - + // Map a reference thread and insert it into the queue _threadMap.set(impl); - + ThreadQueue::instance()->insertReferenceThread(impl); - + } - + assert(impl != 0); return impl; - + } - + /** * Make current thread sleep for the given number of milliseconds. * This sleep can be interrupt()ed. - * + * * @param ms timeout for the sleep. * * @post the calling thread is blocked by waiting on the internal condition * variable. This can be signaled in the monitor of an interrupt */ void ThreadImpl::sleep(unsigned long ms) { - + // Make sleep()ing for 0 milliseconds equivalent to a yield. if(ms == 0) { - + yield(); return; - + } - + // Get the monitor for the current thread Monitor& monitor = current()->getMonitor(); - + // Acquire that threads Monitor with a Guard Guard<Monitor> g(monitor); - + for(;;) { - + switch(monitor.wait(ms)) { - + case Monitor::INTERRUPTED: throw Interrupted_Exception(); - + default: return; - + } - + } - + } - - + + /** - * Yield the current timeslice to another thread. - * If sched_yield() is available it is used. + * Yield the current timeslice to another thread. + * If sched_yield() is available it is used. * Otherwise, the state Monitor for this thread is used to simiulate a - * yield by blocking for 1 millisecond, which should give the + * yield by blocking for 1 millisecond, which should give the * scheduler a chance to schedule another thread. */ void ThreadImpl::yield() { - - // Try to yield with the native operation. If it fails, then + + // Try to yield with the native operation. If it fails, then // simulate with a short wait() on the monitor. if(!ThreadOps::yield()) { - + // Get the monitor for the current thread Monitor& monitor = current()->getMonitor(); - + // Attempt a wait(). - Guard<Monitor> g(monitor); + Guard<Monitor> g(monitor); monitor.wait(1); - + } - + } void ThreadImpl::start(const Task& task) { @@ -338,9 +338,9 @@ namespace ZThread { // A Thread must be idle in order to be eligable to run a task. if(!_state.isIdle()) throw InvalidOp_Exception("Thread is not idle."); - + _state.setRunning(); - + // Spawn a new thread, blocking the parent (current) thread until // the child starts. @@ -353,14 +353,14 @@ namespace ZThread { if(!spawn(&launch)) { // Return to the idle state & report the error if it doesn't work out. - _state.setIdle(); - throw Synchronization_Exception(); + _state.setIdle(); + throw Synchronization_Exception(); } // Wait, uninterruptably, for the child's signal. The parent thread - // still can be interrupted and killed; it just won't take effect + // still can be interrupted and killed; it just won't take effect // until the child has started. Guard<Monitor, DeferredInterruptionScope> g3(parent->_monitor); @@ -368,7 +368,7 @@ namespace ZThread { if(parent->_monitor.wait() != Monitor::SIGNALED) { assert(0); } - + } @@ -378,23 +378,23 @@ namespace ZThread { // Map the implementation object onto the running thread. _threadMap.set(impl); - // Update the reference count on a ThreadImpl before the 'Thread' + // Update the reference count on a ThreadImpl before the 'Thread' // that owns it can go out of scope (by signaling the parent) impl->addReference(); // Update the priority of the thread - if(parent->_state.isReference()) - ThreadOps::setPriority(impl, + if(parent->_state.isReference()) + ThreadOps::setPriority(impl, parent->_state.isReference() ? impl->_priority : parent->_priority); // Inherit ThreadLocal values from the parent typedef ThreadLocalMap::const_iterator It; - for(It i = parent->getThreadLocalMap().begin(); i != parent->getThreadLocalMap().end(); ++i) + for(It i = parent->getThreadLocalMap().begin(); i != parent->getThreadLocalMap().end(); ++i) if( (i->second)->isInheritable() ) impl->getThreadLocalMap()[ i->first ] = (i->second)->clone(); - - // Insert a user-thread mapping + + // Insert a user-thread mapping ThreadQueue::instance()->insertUserThread(impl); // Wake the parent once the thread is setup parent->_monitor.notify(); @@ -403,65 +403,65 @@ namespace ZThread { // not catch exceptions, let program terminate //try { - + task->run(); //} catch(...) { // Result of running a task that threw an exception. // ZTDEBUG("The task has thrown an unhandled exception\n"); - //assert(0); // UQ1: Go to debugger... - + //assert(0); // UQ1: Go to debugger... + //} - ZTDEBUG("Thread joining...\n"); - + ZTDEBUG("Thread joining...\n"); + { // Update the state of the thread - + Guard<Monitor> g(impl->_monitor); impl->_state.setJoined(); - + // Wake the joiners that will be easy to join first for(List::iterator i = impl->_joiners.begin(); i != impl->_joiners.end();) { - + ThreadImpl* joiner = *i; Monitor& m = joiner->getMonitor(); if(m.tryAcquire()) { - + m.notify(); - m.release(); - + m.release(); + i = impl->_joiners.erase(i); } else ++i; - } + } // Wake the joiners that might take a while next for(List::iterator i = impl->_joiners.begin(); i != impl->_joiners.end(); ++i) { - + ThreadImpl* joiner = *i; Monitor& m = joiner->getMonitor(); m.acquire(); m.notify(); - m.release(); - + m.release(); + } - + } - ZTDEBUG("Thread exiting...\n"); + ZTDEBUG("Thread exiting...\n"); - // Insert a pending-thread mapping, allowing the resources to be reclaimed + // Insert a pending-thread mapping, allowing the resources to be reclaimed ThreadQueue::instance()->insertPendingThread(impl); // Cleanup ThreadLocal values impl->getThreadLocalMap().clear(); - // Update the reference count allowing it to be destroyed + // Update the reference count allowing it to be destroyed impl->delReference(); } |