void Lock::doChecksBeforeWaiting() { // Check if the interrupts are set. Else, we maybe wait forever checkInterrupts("Lock::doChecksBeforeWaiting"); // Check if the thread has been waken up even if he is already waiting on another lock. checkCurrentThreadStillWaitingOnAnotherLock(); // Check if locking this lock would result in a deadlock. checkForDeadLock(); }
void Condition::signal(pointer called_by) { if(unlikely(system_state != RUNNING)) return; if(!called_by) called_by = getCalledBefore(1); // debug(LOCK, "Condition::signal: Thread %s (%p) is signaling condition %s (%p).\n", // currentThread->getName(), currentThread, getName(), this); // debug(LOCK, "The signal is called by: "); // kernel_debug_info->printCallInformation(called_by); assert(mutex_->isHeldBy(currentThread)); checkInterrupts("Condition::signal"); lockWaitersList(); last_accessed_at_ = called_by; Thread* thread_to_be_woken_up = popBackThreadFromWaitersList(); unlockWaitersList(); if(thread_to_be_woken_up) { if(likely(thread_to_be_woken_up->state_ == Sleeping)) { // In this case we can access the pointer of the other thread without locking, // because we can ensure that the thread is sleeping. //debug(LOCK, "Condition: Thread %s (%p) being signaled for condition %s (%p).\n", // thread_to_be_woken_up->getName(), thread_to_be_woken_up, getName(), this); thread_to_be_woken_up->lock_waiting_on_ = 0; Scheduler::instance()->wake(thread_to_be_woken_up); } else { debug(LOCK, "ERROR: Condition %s (%p): Thread %s (%p) is in state %s AND waiting on the condition!\n", getName(), this, thread_to_be_woken_up->getName(), thread_to_be_woken_up, Thread::threadStatePrintable[thread_to_be_woken_up->state_]); assert(false); } } }
void Condition::wait(bool re_acquire_mutex, pointer called_by) { if(unlikely(system_state != RUNNING)) return; if(!called_by) called_by = getCalledBefore(1); // debug(LOCK, "Condition::wait: Thread %s (%p) is waiting on condition %s (%p).\n", // currentThread->getName(), currentThread, getName(), this); // if(kernel_debug_info) // { // debug(LOCK, "The wait is called by: "); // kernel_debug_info->printCallInformation(called_by); // } assert(mutex_->isHeldBy(currentThread)); // check if the interrupts are enabled and the thread is not waiting for some other locks checkInterrupts("Condition::wait"); checkCurrentThreadStillWaitingOnAnotherLock(); assert(currentThread->holding_lock_list_); if(currentThread->holding_lock_list_->hasNextOnHoldingList()) { debug(LOCK, "Condition::wait: Warning: The thread %s (%p) is holding some locks when going to sleep on condition %s (%p).\n" "This may lower the performance of the system, and cause undetectable deadlocks!\n", currentThread->getName(), currentThread, getName(), this); printHoldingList(currentThread); } lockWaitersList(); last_accessed_at_ = called_by; // The mutex can be released here, because for waking up another thread, the list lock is needed, which is still held by the thread. mutex_->release(called_by); Scheduler::instance()->sleepAndRelease(*(Lock*)this); if(re_acquire_mutex) { assert(mutex_); mutex_->acquire(called_by); } }
void Renderer::renderPart(std::vector<PhotonMap::NearestPhoton>& nearestPhotons, Segment2i const& segment) { Extent2i sufraceExtent = surface()->extent(); if (quality() < 0) { float idealSampleSize = 1 << -quality(); Extent2i pixelCount = extent(segment); idealSampleSize = min(idealSampleSize, (float)pixelCount.x); idealSampleSize = min(idealSampleSize, (float)pixelCount.y); Extent2i sampleCount; sampleCount.x = pixelCount.x / idealSampleSize; sampleCount.y = pixelCount.y / idealSampleSize; Extent2i pixelCountPerSample; pixelCountPerSample.x = pixelCount.x / sampleCount.x; pixelCountPerSample.y = pixelCount.y / sampleCount.y; Extent2i leftoverPixelCount; leftoverPixelCount.x = pixelCount.x - pixelCountPerSample.x * sampleCount.x; leftoverPixelCount.y = pixelCount.y - pixelCountPerSample.y * sampleCount.y; Point2i pixelPositionBegin; Point2i pixelPositionEnd; Point2f samplePosition; Point2i sample; for (sample.y = 0; sample.y < sampleCount.y; ++sample.y) { pixelPositionBegin.y = segment.min.y + pixelCountPerSample.y * (sample.y + 0) + min(sample.y + 0, leftoverPixelCount.y); pixelPositionEnd.y = segment.min.y + pixelCountPerSample.y * (sample.y + 1) + min(sample.y + 1, leftoverPixelCount.y); samplePosition.y = floor((pixelPositionBegin.y + pixelPositionEnd.y) / 2.0f); for (sample.x = 0; sample.x < sampleCount.x; ++sample.x) { pixelPositionBegin.x = segment.min.x + pixelCountPerSample.x * (sample.x + 0) + min(sample.x + 0, leftoverPixelCount.x); pixelPositionEnd.x = segment.min.x + pixelCountPerSample.x * (sample.x + 1) + min(sample.x + 1, leftoverPixelCount.x); samplePosition.x = floor((pixelPositionBegin.x + pixelPositionEnd.x) / 2.0f); Ray ray = camera()->cast(samplePosition, sufraceExtent); Color sampleColor = render(nearestPhotons, ray); Color pixelColor = clamp(Color::BLACK, sampleColor, Color::WHITE); Point2i pixelPosition; for (pixelPosition.y = pixelPositionBegin.y; pixelPosition.y < pixelPositionEnd.y; ++pixelPosition.y) { for (pixelPosition.x = pixelPositionBegin.x; pixelPosition.x < pixelPositionEnd.x; ++pixelPosition.x) { checkInterrupts(); surface()->setPixel(pixelPosition, pixelColor); } } } } } else { int sampleCount = 1 << quality(); float sampleDistance = 1.0f / sampleCount; float sampleWeight = 1.0f / sqr(sampleCount); Point2i pixelPosition; for (pixelPosition.y = segment.min.y; pixelPosition.y < segment.max.y; ++pixelPosition.y) { for (pixelPosition.x = segment.min.x; pixelPosition.x < segment.max.x; ++pixelPosition.x) { checkInterrupts(); Color sampleColor = Color::BLACK; Point2f subPixelPosition; for (subPixelPosition.y = sampleDistance / 2.0f; subPixelPosition.y < 1.0f; subPixelPosition.y += sampleDistance) { for (subPixelPosition.x = sampleDistance / 2.0f; subPixelPosition.x < 1.0f; subPixelPosition.x += sampleDistance) { Point2f samplePosition = Point2f(pixelPosition.x + subPixelPosition.x, pixelPosition.y + subPixelPosition.y); Ray ray = camera()->cast(samplePosition, sufraceExtent); sampleColor += render(nearestPhotons, ray) * sampleWeight; } } Color pixelColor = clamp(Color::BLACK, sampleColor, Color::WHITE); surface()->setPixel(pixelPosition, pixelColor); } } } }