void HouseKeeper::Start(void) { // no need to be fine grained, nothing else should be accessing this map QMutexLocker mapLock(&m_mapLock); if (m_timer->isActive()) // Start() should only be called once return; MSqlQuery query(MSqlQuery::InitCon()); query.prepare("SELECT tag,lastrun" " FROM housekeeping" " WHERE hostname = :HOST" " OR hostname IS NULL"); query.bindValue(":HOST", gCoreContext->GetHostName()); if (!query.exec()) MythDB::DBError("HouseKeeper::Run", query); else { while (query.next()) { // loop through housekeeping table and load last run timestamps QString tag = query.value(0).toString(); QDateTime lastrun = MythDate::as_utc(query.value(1).toDateTime()); if (m_taskMap.contains(tag)) m_taskMap[tag]->SetLastRun(lastrun); } } gCoreContext->addListener(this); QMap<QString,HouseKeeperTask*>::const_iterator it; for (it = m_taskMap.begin(); it != m_taskMap.end(); ++it) { if ((*it)->CheckImmediate()) { // run any tasks marked for immediate operation in-thread (*it)->UpdateLastRun(); (*it)->Run(); } else if ((*it)->CheckStartup()) { // queue any tasks marked for startup LOG(VB_GENERAL, LOG_INFO, QString("Queueing HouseKeeperTask '%1'.").arg(it.key())); QMutexLocker queueLock(&m_queueLock); (*it)->IncrRef(); m_taskQueue.enqueue(*it); } } LOG(VB_GENERAL, LOG_INFO, "Starting HouseKeeper."); if (!m_taskQueue.isEmpty()) StartThread(); m_timer->start(); }
REFERENCE_TIME CWASAPIRenderFilter::BufferredDataDuration() { REFERENCE_TIME rtDuration = 0; REFERENCE_TIME rtStart = 0; REFERENCE_TIME rtStop = 0; HRESULT hr = S_OK; { CAutoLock queueLock(&m_inputQueueLock); vector<TQueueEntry>::iterator it = m_inputQueue.begin(); while (it != m_inputQueue.end()) { // EOS marker is currently a NULL sample if (it->Sample) { if (SUCCEEDED(hr = it->Sample->GetTime(&rtStart, &rtStop))) rtDuration += rtStop - rtStart; else Log("CWASAPIRenderFilter::BufferredDataDuration Failed to get sample times"); } ++it; } } CAutoLock lock(&m_csCurrentSample); if (m_pCurrentSample.p) { UINT nFrames = (m_pCurrentSample.p->GetActualDataLength() - m_nSampleOffset) / m_pInputFormat->Format.nBlockAlign; rtDuration += nFrames * UNITS / m_pInputFormat->Format.nSamplesPerSec; } return rtDuration; }
void TaskDispatcher2::addTask(TaskJob &&task) { { std::lock_guard<std::mutex> queueLock(m_queueMutex); m_taskQueue.push(std::move(task)); } m_condition.notify_all(); }
// Get the next sample in the queue. If there is none, wait for at most // dwTimeout milliseconds for one to become available before failing. // Returns: S_FALSE if no sample available // Threading: only one thread should be calling GetNextSampleOrCommand() // but it can be different from the one calling PutSample()/PutCommand() HRESULT CQueuedAudioSink::GetNextSampleOrCommand(AudioSinkCommand* pCommand, IMediaSample** pSample, DWORD dwTimeout, vector<HANDLE>* pHandles, vector<DWORD>* pWaitObjects, bool handleOOBOnly) { HRESULT hr = WaitForEvents(dwTimeout, pHandles, pWaitObjects); if (hr == MPAR_S_WAIT_TIMED_OUT || hr == S_FALSE) { if (pSample && *pSample && !handleOOBOnly) { (*pSample)->Release(); (*pSample) = NULL; } *pCommand = ASC_Nop; return WAIT_TIMEOUT; } { CAutoLock OOBQueueLock(&m_OOBInputQueueLock); if (!m_OOBInputQueue.empty()) { TQueueEntry entry = m_OOBInputQueue.front(); if (pCommand) *pCommand = entry.Command; m_OOBInputQueue.pop(); if (m_OOBInputQueue.empty()) ResetEvent(m_hOOBCommandAvailableEvent); return S_OK; } else if (handleOOBOnly) { *pCommand = ASC_Nop; return S_OK; } } if (hr != S_OK) return hr; if (pSample && *pSample) (*pSample)->Release(); CAutoLock queueLock(&m_inputQueueLock); TQueueEntry entry = m_inputQueue.front(); if (pSample) *pSample = entry.Sample.Detach(); if (pCommand) *pCommand = entry.Command; m_inputQueue.erase(m_inputQueue.begin()); if (m_inputQueue.empty()) ResetEvent(m_hInputAvailableEvent); //if (m_InputQueue.empty()) // SetEvent(m_hInputQueueEmptyEvent); return S_OK; }
HRESULT CQueuedAudioSink::PutOOBCommand(AudioSinkCommand nCommand) { CAutoLock queueLock(&m_OOBInputQueueLock); m_OOBInputQueue.push(nCommand); SetEvent(m_hOOBCommandAvailableEvent); return S_OK; }
void COverlayRenderer::FreeOverlayQueue(const uint8_t plane) { CAutoLock queueLock(&m_csOverlayQueue); ivecOverlayQueue it = m_overlayQueue[plane].begin(); while (it != m_overlayQueue[plane].end()) { it = FreeOverlay(it); } }
HRESULT CQueuedAudioSink::PutCommand(AudioSinkCommand nCommand) { CAutoLock queueLock(&m_inputQueueLock); m_inputQueue.push_back(nCommand); SetEvent(m_hInputAvailableEvent); //if(m_hInputQueueEmptyEvent) // ResetEvent(m_hInputQueueEmptyEvent); return S_OK; }
HouseKeeper::~HouseKeeper(void) { gCoreContext->removeListener(this); if (m_timer) { m_timer->stop(); disconnect(m_timer); delete m_timer; m_timer = NULL; } { // remove anything from the queue first, so it does not start QMutexLocker queueLock(&m_queueLock); while (!m_taskQueue.isEmpty()) m_taskQueue.takeFirst()->DecrRef(); } { // issue a terminate call to any long-running tasks // this is just a noop unless overwritten by a subclass QMutexLocker mapLock(&m_mapLock); QMap<QString,HouseKeeperTask*>::iterator it = m_taskMap.begin(); for (; it != m_taskMap.end(); ++it) (*it)->Terminate(); } if (!m_threadList.isEmpty()) { QMutexLocker threadLock(&m_threadLock); // tell primary thread to self-terminate and wake it m_threadList.first()->Discard(); m_threadList.first()->Wake(); // wait for any remaining threads to self-terminate and close while (!m_threadList.isEmpty()) { HouseKeepingThread *thread = m_threadList.takeFirst(); thread->wait(); delete thread; } } { // unload any registered tasks QMutexLocker mapLock(&m_mapLock); QMap<QString,HouseKeeperTask*>::iterator it = m_taskMap.begin(); while (it != m_taskMap.end()) { (*it)->DecrRef(); it = m_taskMap.erase(it); } } }
TaskDispatcher2::~TaskDispatcher2() { { std::lock_guard<std::mutex> queueLock(m_queueMutex); m_stop = true; } m_condition.notify_all(); for (size_t i{ 0 }; i < m_threadVector.size(); ++i) { if (m_threadVector[i].joinable()) { m_threadVector[i].join(); } } }
// Processing HRESULT CQueuedAudioSink::PutSample(IMediaSample *pSample) { if (m_bFlushing) return S_OK; CAutoLock queueLock(&m_inputQueueLock); m_inputQueue.push_back(pSample); SetEvent(m_hInputAvailableEvent); //if(m_hInputQueueEmptyEvent) // ResetEvent(m_hInputQueueEmptyEvent); return S_OK; }
void TaskDispatcher2::exec() { std::unique_lock<std::mutex> queueLock(m_queueMutex); do { m_condition.wait(queueLock, [this] { return !m_taskQueue.empty() || m_stop; }); if (!m_taskQueue.empty()) { const auto task = std::move(m_taskQueue.front()); m_taskQueue.pop(); queueLock.unlock(); task(); queueLock.lock(); } } while (!m_stop || !m_taskQueue.empty()); }
void Mailbox::push(std::unique_ptr<Message> message) { std::lock_guard<std::mutex> pushingLock(pushingMutex); if (closed) { return; } std::lock_guard<std::mutex> queueLock(queueMutex); bool wasEmpty = queue.empty(); queue.push(std::move(message)); if (wasEmpty) { scheduler.schedule(shared_from_this()); } }
void HouseKeeper::Run(void) { LOG(VB_GENERAL, LOG_DEBUG, "Running HouseKeeper."); QDateTime now = MythDate::current(); QMutexLocker mapLock(&m_mapLock); QMap<QString,HouseKeeperTask*>::const_iterator it; for (it = m_taskMap.begin(); it != m_taskMap.end(); ++it) { if ((*it)->CheckRun(now)) { // check if any tasks are ready to run, and add to queue LOG(VB_GENERAL, LOG_INFO, QString("Queueing HouseKeeperTask '%1'.").arg(it.key())); QMutexLocker queueLock(&m_queueLock); (*it)->IncrRef(); m_taskQueue.enqueue(*it); } } if (!m_taskQueue.isEmpty()) StartThread(); if (m_threadList.size() > 1) { // spent threads exist in the thread list // check to see if any have finished up their task and terminated QMutexLocker threadLock(&m_threadLock); int count1 = m_threadList.size(); QList<HouseKeepingThread*>::iterator it = m_threadList.begin(); ++it; // skip the primary thread while (it != m_threadList.end()) { if ((*it)->isRunning()) ++it; else it = m_threadList.erase(it); } int count2 = m_threadList.size(); if (count1 > count2) LOG(VB_GENERAL, LOG_DEBUG, QString("Discarded HouseKeepingThreads have completed and " "been deleted. Current count %1 -> %2.") .arg(count1).arg(count2)); } }
HouseKeeperTask* HouseKeeper::GetQueuedTask(void) { QMutexLocker queueLock(&m_queueLock); HouseKeeperTask *task = NULL; if (!m_taskQueue.isEmpty()) { task = m_taskQueue.dequeue(); task->IncrRef(); } // returning NULL tells the thread that the queue is empty and // to go into standby return task; }
void ICharacter::consumeHP (const uint32_t amount) { if (amount) { boost::mutex::scoped_lock stats_lock(m_stats_mutex); if (m_HP) { if ( amount > m_HP) m_HP = 0; else m_HP -= amount; if (!m_HP) { stats_lock.unlock(); if (!signal_dead.empty()) signal_dead(m_UniqueID,m_CurrentPos); boost::lock(m_state_mutex,m_queue_mutex,m_mov_mutex); boost::unique_lock<boost::mutex> stateLock(m_state_mutex,boost::adopt_lock); boost::unique_lock<boost::mutex> queueLock(m_queue_mutex,boost::adopt_lock); boost::unique_lock<boost::mutex> moveLock(m_mov_mutex,boost::adopt_lock); if (m_AttackState != ATTACK_ACTION_STOP) { m_AttackState = ATTACK_ACTION_STOP; if (!signal_state.empty()) signal_state(STATE_ATTACK,m_AttackState); } m_StatusState = STATUS_ACTION_DEAD; if (!signal_state.empty()) signal_state(STATE_STATUS,m_StatusState); m_QueueSkill = 0; m_QueueTarget = 0; m_CurrentTask = 0; m_NextPos = Coord(); } } } }
HRESULT CQueuedAudioSink::BeginFlush() { ResetEvent(m_hCurrentSampleReleased); // Request the derived class to release the current sample and stall threadproc PutOOBCommand(ASC_Flush); { CAutoLock queueLock(&m_inputQueueLock); ResetEvent(m_hInputAvailableEvent); while (!m_inputQueue.empty()) m_inputQueue.erase(m_inputQueue.begin()); //SetEvent(m_hInputQueueEmptyEvent); } return CBaseAudioSink::BeginFlush(); }
void retireTask(Task* task) { std::unique_lock<std::mutex> counterLock(m_threadCounterMutex); m_threadsDoneCount++; if (m_threadsDoneCount >= m_totalThreads) { task->notifyComplete(); m_threadsDoneCount = 0; std::unique_lock<std::mutex> queueLock(m_queueMutex); m_tasks.pop(); if (m_tasks.empty()) { m_tasksComplete.notify_all(); } } counterLock.unlock(); m_barrier.wait(); }
void COverlayRenderer::ScheduleOverlays() { CAutoLock queueLock(&m_csOverlayQueue); REFERENCE_TIME rtDue = 0; if (NextScheduleTime(rtDue, BD_OVERLAY_IG)) { LARGE_INTEGER liDueTime; liDueTime.QuadPart = -rtDue; #ifdef LOG_DRAWING LogDebug(" liDueTime: %6.3f", liDueTime.QuadPart / 10000000.0); #endif if (SetWaitableTimer(m_hOverlayTimerIG, &liDueTime, 0, NULL, NULL, 0) == 0) { #ifdef LOG_DRAWING DWORD error = GetLastError(); LogDebug("COverlayRenderer::ScheduleOverlay - SetWaitableTimer failed: %d", error); #endif } } if (NextScheduleTime(rtDue, BD_OVERLAY_PG)) { LARGE_INTEGER liDueTime; liDueTime.QuadPart = -rtDue; #ifdef LOG_DRAWING LogDebug(" liDueTime: %6.3f", liDueTime.QuadPart / 10000000.0); #endif if (SetWaitableTimer(m_hOverlayTimerPG, &liDueTime, 0, NULL, NULL, 0) == 0) { #ifdef LOG_DRAWING DWORD error = GetLastError(); LogDebug("COverlayRenderer::ScheduleOverlay - SetWaitableTimer failed: %d", error); #endif } } }
void AsyncThreadManager::itemConsumer(WorkQueue& workQueue, condition_variable& workAvailable, recursive_mutex& queueMutex, bool &finished) { while(true) { cz::unique_lock<cz::recursive_mutex> queueLock(queueMutex); while(!finished && workQueue.empty()) workAvailable.wait(queueLock); if (finished) break; detail::AsyncWorkItemBase* workItem = workQueue.front(); workQueue.pop(); // unlock so other threads can remove work items while we compute this one queueLock.unlock(); // Compute the result (this will put the value in the "future" object the user is holding) workItem->run(); CZ_DELETE workItem; } }
void COverlayRenderer::OverlayProc(const BD_OVERLAY* ov) { if (!ov) return; if (ov->cmd == BD_OVERLAY_CLOSE || ov->cmd == BD_OVERLAY_INIT) { ProcessOverlay(ov); return; } BD_OVERLAY_EX *copy = (BD_OVERLAY_EX*)malloc(sizeof(BD_OVERLAY_EX)); if (!copy) return; memcpy(copy, ov, sizeof(*ov)); copy->scheduled = false; if (ov->palette) { copy->palette = (BD_PG_PALETTE_ENTRY*)malloc(PALETTE_SIZE * sizeof(BD_PG_PALETTE_ENTRY)); memcpy((void*)copy->palette, ov->palette, PALETTE_SIZE * sizeof(BD_PG_PALETTE_ENTRY)); } if (copy->img) m_pLib->IncreaseRefCount(copy->img); { #ifdef LOG_DRAWING LogDebug("new arriva PTS: %6.3f wait: %6.3f", (CONVERT_90KHz_DS(copy->pts)) / 10000000.0); #endif CAutoLock queueLock(&m_csOverlayQueue); m_overlayQueue[copy->plane].push_back(copy); SetEvent(m_hNewOverlayAvailable); } }
COverlayRenderer::~COverlayRenderer() { CAutoLock renderLock(&m_csRenderLock); CAutoLock queueLock(&m_csOverlayQueue); FreeOverlayQueue(BD_OVERLAY_IG); FreeOverlayQueue(BD_OVERLAY_PG); if (m_hOverlayTimerIG) { CloseHandle(m_hOverlayTimerIG); m_hOverlayTimerIG = NULL; } if (m_hOverlayTimerPG) { CloseHandle(m_hOverlayTimerPG); m_hOverlayTimerPG = NULL; } if (m_hNewOverlayAvailable) CloseHandle(m_hNewOverlayAvailable); if (m_hStopThreadEvent) { SetEvent(m_hStopThreadEvent); CloseHandle(m_hStopThreadEvent); WaitForSingleObject(m_hThread, INFINITE); } if (m_hThread) CloseHandle(m_hThread); CloseOverlay(BD_OVERLAY_PG); CloseOverlay(BD_OVERLAY_IG); }
void S3KeyWriter::flushBuffer() { if (!this->buffer.empty()) { UniqueLock queueLock(&this->mutex); while (this->activeThreads >= this->params.getNumOfChunks()) { pthread_cond_wait(&this->cv, &this->mutex); } // Most time query is canceled during uploadPartOfData(). This is the first chance to cancel // and clean up upload. this->checkQueryCancelSignal(); this->activeThreads++; pthread_t writerThread; ThreadParams* params = new ThreadParams(); params->keyWriter = this; params->data.swap(this->buffer); params->currentNumber = ++this->partNumber; pthread_create(&writerThread, NULL, UploadThreadFunc, params); threadList.emplace_back(writerThread); this->buffer.reserve(this->params.getChunkSize()); } }
void Mailbox::receive() { std::lock_guard<std::recursive_mutex> receivingLock(receivingMutex); if (closed) { return; } std::unique_ptr<Message> message; bool wasEmpty; { std::lock_guard<std::mutex> queueLock(queueMutex); assert(!queue.empty()); message = std::move(queue.front()); queue.pop(); wasEmpty = queue.empty(); } (*message)(); if (!wasEmpty) { scheduler.schedule(shared_from_this()); } }
REFERENCE_TIME CWASAPIRenderFilter::BufferredDataDuration() { CAutoLock queueLock(&m_inputQueueLock); REFERENCE_TIME rtDuration = 0; REFERENCE_TIME rtStart = 0; REFERENCE_TIME rtStop = 0; vector<TQueueEntry>::iterator it = m_inputQueue.begin(); while (it != m_inputQueue.end()) { it->Sample->GetTime(&rtStart, &rtStop); rtDuration += rtStop - rtStart; ++it; } if (m_pCurrentSample.p) { UINT nFrames = (m_pCurrentSample.p->GetActualDataLength() - m_nSampleOffset) / m_pInputFormat->Format.nBlockAlign; rtDuration += nFrames * UNITS / m_pInputFormat->Format.nSamplesPerSec; } return rtDuration; }
/** * The thread method that handles calling send for the individual sockets. * * Control packets will always be tried to be sent first. If there is any bandwidth leftover * after that, send() for the upload slot sockets will be called in priority order until we have run * out of available bandwidth for this loop. Upload slots will not be allowed to go without having sent * called for more than a defined amount of time (i.e. two seconds). * * @return always returns 0. */ void* UploadBandwidthThrottler::Entry() { const uint32 TIME_BETWEEN_UPLOAD_LOOPS = 1; uint32 lastLoopTick = GetTickCountFullRes(); // Bytes to spend in current cycle. If we spend more this becomes negative and causes a wait next time. sint32 bytesToSpend = 0; uint32 allowedDataRate = 0; uint32 rememberedSlotCounter = 0; uint32 extraSleepTime = TIME_BETWEEN_UPLOAD_LOOPS; while (m_doRun && !TestDestroy()) { uint32 timeSinceLastLoop = GetTickCountFullRes() - lastLoopTick; // Calculate data rate if (thePrefs::GetMaxUpload() == UNLIMITED) { // Try to increase the upload rate from UploadSpeedSense allowedDataRate = (uint32)theStats::GetUploadRate() + 5 * 1024; } else { allowedDataRate = thePrefs::GetMaxUpload() * 1024; } uint32 minFragSize = 1300; uint32 doubleSendSize = minFragSize*2; // send two packages at a time so they can share an ACK if (allowedDataRate < 6*1024) { minFragSize = 536; doubleSendSize = minFragSize; // don't send two packages at a time at very low speeds to give them a smoother load } uint32 sleepTime; if (bytesToSpend < 1) { // We have sent more than allowed in last cycle so we have to wait now // until we can send at least 1 byte. sleepTime = std::max((-bytesToSpend + 1) * 1000 / allowedDataRate + 2, // add 2 ms to allow for rounding inaccuracies extraSleepTime); } else { // We could send at once, but sleep a while to not suck up all cpu sleepTime = extraSleepTime; } if (timeSinceLastLoop < sleepTime) { Sleep(sleepTime-timeSinceLastLoop); } // Check after sleep in case the thread has been signaled to end if (!m_doRun || TestDestroy()) { break; } const uint32 thisLoopTick = GetTickCountFullRes(); timeSinceLastLoop = thisLoopTick - lastLoopTick; lastLoopTick = thisLoopTick; if (timeSinceLastLoop > sleepTime + 2000) { AddDebugLogLineN(logGeneral, CFormat(wxT("UploadBandwidthThrottler: Time since last loop too long. time: %ims wanted: %ims Max: %ims")) % timeSinceLastLoop % sleepTime % (sleepTime + 2000)); timeSinceLastLoop = sleepTime + 2000; } // Calculate how many bytes we can spend bytesToSpend += (sint32) (allowedDataRate / 1000.0 * timeSinceLastLoop); if (bytesToSpend >= 1) { sint32 spentBytes = 0; sint32 spentOverhead = 0; wxMutexLocker sendLock(m_sendLocker); { wxMutexLocker queueLock(m_tempQueueLocker); // are there any sockets in m_TempControlQueue_list? Move them to normal m_ControlQueue_list; m_ControlQueueFirst_list.insert( m_ControlQueueFirst_list.end(), m_TempControlQueueFirst_list.begin(), m_TempControlQueueFirst_list.end() ); m_ControlQueue_list.insert( m_ControlQueue_list.end(), m_TempControlQueue_list.begin(), m_TempControlQueue_list.end() ); m_TempControlQueue_list.clear(); m_TempControlQueueFirst_list.clear(); } // Send any queued up control packets first while (spentBytes < bytesToSpend && (!m_ControlQueueFirst_list.empty() || !m_ControlQueue_list.empty())) { ThrottledControlSocket* socket = NULL; if (!m_ControlQueueFirst_list.empty()) { socket = m_ControlQueueFirst_list.front(); m_ControlQueueFirst_list.pop_front(); } else if (!m_ControlQueue_list.empty()) { socket = m_ControlQueue_list.front(); m_ControlQueue_list.pop_front(); } if (socket != NULL) { SocketSentBytes socketSentBytes = socket->SendControlData(bytesToSpend-spentBytes, minFragSize); spentBytes += socketSentBytes.sentBytesControlPackets + socketSentBytes.sentBytesStandardPackets; spentOverhead += socketSentBytes.sentBytesControlPackets; } } // Check if any sockets haven't gotten data for a long time. Then trickle them a package. uint32 slots = m_StandardOrder_list.size(); for (uint32 slotCounter = 0; slotCounter < slots; slotCounter++) { ThrottledFileSocket* socket = m_StandardOrder_list[ slotCounter ]; if (socket != NULL) { if (thisLoopTick-socket->GetLastCalledSend() > SEC2MS(1)) { // trickle uint32 neededBytes = socket->GetNeededBytes(); if (neededBytes > 0) { SocketSentBytes socketSentBytes = socket->SendFileAndControlData(neededBytes, minFragSize); spentBytes += socketSentBytes.sentBytesControlPackets + socketSentBytes.sentBytesStandardPackets; spentOverhead += socketSentBytes.sentBytesControlPackets; } } } else { AddDebugLogLineN(logGeneral, CFormat( wxT("There was a NULL socket in the UploadBandwidthThrottler Standard list (trickle)! Prevented usage. Index: %i Size: %i")) % slotCounter % m_StandardOrder_list.size()); } } // Give available bandwidth to slots, starting with the one we ended with last time. // There are two passes. First pass gives packets of doubleSendSize, second pass // gives as much as possible. // Second pass starts with the last slot of the first pass actually. for (uint32 slotCounter = 0; (slotCounter < slots * 2) && spentBytes < bytesToSpend; slotCounter++) { if (rememberedSlotCounter >= slots) { // wrap around pointer rememberedSlotCounter = 0; } uint32 data = (slotCounter < slots - 1) ? doubleSendSize // pass 1 : (bytesToSpend - spentBytes); // pass 2 ThrottledFileSocket* socket = m_StandardOrder_list[ rememberedSlotCounter ]; if (socket != NULL) { SocketSentBytes socketSentBytes = socket->SendFileAndControlData(data, doubleSendSize); spentBytes += socketSentBytes.sentBytesControlPackets + socketSentBytes.sentBytesStandardPackets; spentOverhead += socketSentBytes.sentBytesControlPackets; } else { AddDebugLogLineN(logGeneral, CFormat(wxT("There was a NULL socket in the UploadBandwidthThrottler Standard list (equal-for-all)! Prevented usage. Index: %i Size: %i")) % rememberedSlotCounter % m_StandardOrder_list.size()); } rememberedSlotCounter++; } // Do some limiting of what we keep for the next loop. bytesToSpend -= spentBytes; sint32 minBytesToSpend = (slots + 1) * minFragSize; if (bytesToSpend < - minBytesToSpend) { bytesToSpend = - minBytesToSpend; } else { sint32 bandwidthSavedTolerance = slots * 512 + 1; if (bytesToSpend > bandwidthSavedTolerance) { bytesToSpend = bandwidthSavedTolerance; } } m_SentBytesSinceLastCall += spentBytes; m_SentBytesSinceLastCallOverhead += spentOverhead; if (spentBytes == 0) { // spentBytes includes the overhead extraSleepTime = std::min<uint32>(extraSleepTime * 5, 1000); // 1s at most } else { extraSleepTime = TIME_BETWEEN_UPLOAD_LOOPS; } } } { wxMutexLocker queueLock(m_tempQueueLocker); m_TempControlQueue_list.clear(); m_TempControlQueueFirst_list.clear(); } wxMutexLocker sendLock(m_sendLocker); m_ControlQueue_list.clear(); m_StandardOrder_list.clear(); return 0; }
void MemoryMapBuilderCS::run() { _interrupted = false; // Holds the data that is shared among all threads BuilderSharedState* shared = _map->_shared; MemoryMapNode* node = 0; // Now work through the whole stack QMutexLocker queueLock(&shared->queueLock); while ( !_interrupted && !shared->queue.isEmpty() && // shared->processed < 1000 && (!shared->lastNode || shared->lastNode->probability() >= shared->minProbability) ) { // Take element with highest probability node = shared->queue.takeLargest(); shared->lastNode = node; ++shared->processed; queueLock.unlock(); // try to save the physical mapping try { int pageSize; quint64 physAddr = _map->_vmem->virtualToPhysical(node->address(), &pageSize); // Linear memory region or paged memory? if (pageSize < 0) { PhysMemoryMapNode pNode( physAddr, node->size() > 0 ? physAddr + node->size() - 1 : physAddr, node); shared->pmemMapLock.lockForWrite(); _map->_pmemMap.insert(pNode); shared->pmemMapLock.unlock(); } else { // Add all pages a type belongs to quint32 size = node->size(); quint64 virtAddr = node->address(); quint64 pageMask = ~(pageSize - 1); while (size > 0) { physAddr = _map->_vmem->virtualToPhysical(virtAddr, &pageSize); // How much space is left on current page? quint32 sizeOnPage = pageSize - (virtAddr & ~pageMask); if (sizeOnPage > size) sizeOnPage = size; PhysMemoryMapNode pNode( physAddr, physAddr + sizeOnPage - 1, node); // Add a memory mapping shared->pmemMapLock.lockForWrite(); _map->_pmemMap.insert(pNode); shared->pmemMapLock.unlock(); // Subtract the available space from left-over size size -= sizeOnPage; // Advance address virtAddr += sizeOnPage; } } } catch (VirtualMemoryException&) { // Lock the mutex again before we jump to the loop condition checking queueLock.relock(); // Don't proceed any further in case of an exception continue; } processNode(node); // Lock the mutex again before we jump to the loop condition checking queueLock.relock(); } }
DWORD COverlayRenderer::ScheduleThread() { const DWORD eventArraySize = 4; HANDLE handles[eventArraySize]; handles[0] = m_hStopThreadEvent; handles[1] = m_hOverlayTimerIG; handles[2] = m_hOverlayTimerPG; handles[3] = m_hNewOverlayAvailable; DWORD stopThread = WAIT_OBJECT_0; DWORD processOverlayIG = WAIT_OBJECT_0 + 1; DWORD processOverlayPG = WAIT_OBJECT_0 + 2; DWORD newOverlayAvailable = WAIT_OBJECT_0 + 3; while (true) { ScheduleOverlays(); DWORD result = WaitForMultipleObjects(eventArraySize, handles, false, INFINITE); if (result == WAIT_FAILED) return 0; else if (result == stopThread) return 0; else if(result == newOverlayAvailable) { CAutoLock queueLock(&m_csOverlayQueue); ResetEvent(m_hNewOverlayAvailable); #ifdef LOG_DRAWING LogDebug("newOverlayAvailable"); #endif } else if (result == processOverlayIG || result == processOverlayPG) { UINT8 plane = result == processOverlayIG ? BD_OVERLAY_IG : BD_OVERLAY_PG; CAutoLock queueLock(&m_csOverlayQueue); if (!m_overlayQueue[plane].empty()) { ivecOverlayQueue it = m_overlayQueue[plane].begin(); if ((*it)) { #ifdef LOG_DRAWING LogDebug("RENDERING PTS: %6.3f", (CONVERT_90KHz_DS((*it)->pts) + m_rtOffset) / 10000000.0); #endif // close frees all overlays bool freeOverlay = (*it)->cmd != BD_OVERLAY_CLOSE; ProcessOverlay((*it)); if (freeOverlay) FreeOverlay(it); } else FreeOverlay(it); } } } return 0; }
size_t TaskDispatcher2::queuedTaskCount() const { std::lock_guard<std::mutex> queueLock(m_queueMutex); return m_taskQueue.size(); }
void TaskDispatcher2::removeAllTasks() { std::queue<TaskJob> emptyQueue; std::lock_guard<std::mutex> queueLock(m_queueMutex); std::swap(m_taskQueue, emptyQueue); }