void ConsumerThread(int id) { LOG("Starting consumer thread " << id); for(;;) { { Mutex::Lock __(ItemBufferLock); while(QueueSize == 0 && !StopRequested) ItemBufferNotEmpty.Wait(ItemBufferLock); if(StopRequested && QueueSize == 0) break; int Item = ItemBuffer[QueueStartOffset]; QueueSize--; QueueStartOffset++; TotalItemsConsumed++; if(QueueStartOffset == BUFFER_SIZE) QueueStartOffset = 0; LOG("Consumer " << id << ", item " << Item << ", queue size " << QueueSize); } ItemBufferNotFull.Signal(); Sleep(Random(CONSUMER_SLEEP_TIME_MS)); } LOG("Consumer exiting"); }
int WinMonitorData::RegisterCondition( unsigned int cvid ) { int ret = -1; assert( hMutex != NULL ); // check if there is already a condition associated with the chosen id if( cvmap[cvid] == NULL ) { // there was no condition already associated with this condition var // build one ConditionVariable* newcv = new ConditionVariable( hMutex ); // initialize the condition variable if( newcv->Init() == 0 ) { cvmap[cvid] = newcv; ret = 0; } else { // failed to initialized - release the object delete newcv; } } return ret; }
void ProducerThread() { LOG("Starting producer thread"); for(;;) { Sleep(Random(PRODUCER_SLEEP_TIME_MS)); { Mutex::Lock __(ItemBufferLock); while(QueueSize == BUFFER_SIZE && !StopRequested) ItemBufferNotFull.Wait(ItemBufferLock); if(StopRequested) break; int Item = Random(1000); ItemBuffer[(QueueStartOffset + QueueSize) % BUFFER_SIZE] = Item; QueueSize++; TotalItemsProduced++; LOG("Producer item " << Item << ", queue size " << QueueSize); } ItemBufferNotEmpty.Signal(); } LOG("Producer exiting"); }
void Algorithm::RunParallel(set<Algorithm*> algos, Graph& G, vector<string> parameters, float MaxApproximationDistance, float MinCorrectnessProbability) { set<Algorithm*> SelectedAlgorithms; for(set<Algorithm*>::iterator i = algos.begin(); i != algos.end(); i++) if((*i)->SuitableFor(G) && (*i)->CanGuaranteeApproximationDistance(G, MaxApproximationDistance) && (*i)->CanGuaranteeCorrectnessProbability(G, MinCorrectnessProbability)) SelectedAlgorithms.insert(*i); if(SelectedAlgorithms.size() == 0) { throw "No suitable algorithm found"; } else if(SelectedAlgorithms.size() == 1) // we have 1 algorithm => no multithreading needed { Algorithm* algo = *SelectedAlgorithms.begin(); algo->Run(G, parameters); } else { // we have more than 1 algorithm => run them in parallel // give each algorithm its own copy of G map<Thread*, Graph*> GraphCopies; for(set<Algorithm*>::iterator i = SelectedAlgorithms.begin(); i != SelectedAlgorithms.end(); i++) GraphCopies[*i] = new Graph(G); ConditionVariable synchronize; Thread* finishedAlgorithm = NULL; synchronize.Lock(); cerr << "starting " << SelectedAlgorithms.size() << " of " << algos.size() << " algorithms\n"; for(set<Algorithm*>::iterator i = SelectedAlgorithms.begin(); i != SelectedAlgorithms.end(); i++) (*i)->RunInThread(GraphCopies[*i], parameters, &synchronize, &finishedAlgorithm); while(finishedAlgorithm == NULL) // a mislead interrupt can cause the Wait to stop, therefore synchronize.Wait(); // this has to be in a loop that checks whether someone has actually finished G = *(GraphCopies[finishedAlgorithm]); cerr << "someone finished. sending termination requests\n"; for(set<Algorithm*>::iterator i = SelectedAlgorithms.begin(); i != SelectedAlgorithms.end(); i++) (*i)->Terminate(); synchronize.Unlock(); cerr << "waiting for threads to join\n"; for(set<Algorithm*>::iterator i = SelectedAlgorithms.begin(); i != SelectedAlgorithms.end(); i++) { (*i)->Join(); delete GraphCopies[*i]; } GraphCopies.clear(); cerr << "everyone joined\n"; } }
static status_t acpi_battery_control(void* _cookie, uint32 op, void* arg, size_t len) { battery_device_cookie* device = (battery_device_cookie*)_cookie; status_t err; switch (op) { case IDENTIFY_DEVICE: { if (len < sizeof(uint32)) return B_BAD_VALUE; uint32 magicId = kMagicACPIBatteryID; return user_memcpy(arg, &magicId, sizeof(magicId)); } case GET_BATTERY_INFO: { if (len < sizeof(acpi_battery_info)) return B_BAD_VALUE; acpi_battery_info batteryInfo; err = ReadBatteryStatus(device->driver_cookie, &batteryInfo); if (err != B_OK) return err; return user_memcpy(arg, &batteryInfo, sizeof(batteryInfo)); } case GET_EXTENDED_BATTERY_INFO: { if (len < sizeof(acpi_extended_battery_info)) return B_BAD_VALUE; acpi_extended_battery_info extBatteryInfo; err = ReadBatteryInfo(device->driver_cookie, &extBatteryInfo); if (err != B_OK) return err; return user_memcpy(arg, &extBatteryInfo, sizeof(extBatteryInfo)); } case WATCH_BATTERY: sBatteryCondition.Wait(); if (atomic_get(&(device->stop_watching))) { atomic_set(&(device->stop_watching), 0); return B_ERROR; } return B_OK; case STOP_WATCHING_BATTERY: atomic_set(&(device->stop_watching), 1); sBatteryCondition.NotifyAll(); return B_OK; } return B_DEV_INVALID_IOCTL; }
void PhysicalPageSlotQueue::PutSlot(PhysicalPageSlot* slot) { InterruptsLocker locker; slot->next = fSlots; fSlots = slot; if (slot->next == NULL) fFreeSlotCondition.NotifyAll(); else if (slot->next->next == NULL) fFreeSlotCondition.NotifyAll(); }
void Thread::sleep(int ms) { assert(ms >= 0); if (ms > 0) { #ifdef WIN32 Sleep(ms); #else ConditionVariable sleeper; sleeper.acquire(); sleeper.timedWait(ms); sleeper.release(); #endif } else if ( ms == 0 ) yield(); }
/* * Check that a condition variable works */ void ThreadTest::testConditionVariable() { Mutex mutex; ConditionVariable condition; MockConditionThread thread(&mutex, &condition); thread.Start(); mutex.Lock(); if (thread.i != MockConditionThread::EXPECTED) { condition.Wait(&mutex); } OLA_ASSERT_EQ(10, thread.i); mutex.Unlock(); thread.Join(); }
ConditionVariable* ConditionVariable::Create() { ConditionVariable* ptr = new ConditionVariable; if (!ptr) { return nullptr; } const int error = ptr->Construct(); if (error) { delete ptr; return nullptr; } return ptr; }
static void run(void* args) { //assume args is an int int value = *(int*)args; mtx.acquire(); while(counter != value) { // std::cout << "OOOOPSSS Not my turn: " << value << endl; cv.wait(mtx); } cout << "This is run #" << value << endl; counter++; // kThread::currentKT->currentUT->migrate(cluster); cv.signalAll(mtx); }
void Inode::NotifyEndClosed(bool writer) { TRACE("Inode %p::%s(%s)\n", this, __FUNCTION__, writer ? "writer" : "reader"); if (writer) { // Our last writer has been closed; if the pipe // contains no data, unlock all waiting readers TRACE(" buffer readable: %zu\n", fBuffer.Readable()); if (fBuffer.Readable() == 0) { ReadRequestList::Iterator iterator = fReadRequests.GetIterator(); while (ReadRequest* request = iterator.Next()) request->Notify(); if (fReadSelectSyncPool) notify_select_event_pool(fReadSelectSyncPool, B_SELECT_READ); } } else { // Last reader is gone. Wake up all writers. fWriteCondition.NotifyAll(); if (fWriteSelectSyncPool) { notify_select_event_pool(fWriteSelectSyncPool, B_SELECT_WRITE); notify_select_event_pool(fWriteSelectSyncPool, B_SELECT_ERROR); } } }
static status_t low_resource_manager(void*) { bigtime_t timeout = kLowResourceInterval; while (true) { int32 state = low_resource_state_no_update(B_ALL_KERNEL_RESOURCES); if (state != B_LOW_RESOURCE_CRITICAL) { acquire_sem_etc(sLowResourceWaitSem, 1, B_RELATIVE_TIMEOUT, timeout); } RecursiveLocker _(&sLowResourceLock); compute_state(); state = low_resource_state_no_update(B_ALL_KERNEL_RESOURCES); TRACE(("low_resource_manager: state = %ld, %ld free pages, %lld free " "memory, %lu free semaphores\n", state, vm_page_num_free_pages(), vm_available_not_needed_memory(), sem_max_sems() - sem_used_sems())); if (state < B_LOW_RESOURCE_NOTE) continue; call_handlers(sLowResources); if (state == B_LOW_RESOURCE_WARNING) timeout = kWarnResourceInterval; else timeout = kLowResourceInterval; sLowResourceWaiterCondition.NotifyAll(); } return 0; }
void Inode::NotifyBytesRead(size_t bytes) { // notify writer, if something can be written now size_t writable = fBuffer.Writable(); if (bytes > 0) { // notify select()ors only, if nothing was writable before if (writable == bytes) { if (fWriteSelectSyncPool) notify_select_event_pool(fWriteSelectSyncPool, B_SELECT_WRITE); } // If any of the waiting writers has a minimal write count that has // now become satisfied, we notify all of them (condition variables // don't support doing that selectively). WriteRequest* request; WriteRequestList::Iterator iterator = fWriteRequests.GetIterator(); while ((request = iterator.Next()) != NULL) { size_t minWriteCount = request->MinimalWriteCount(); if (minWriteCount > 0 && minWriteCount <= writable && minWriteCount > writable - bytes) { fWriteCondition.NotifyAll(); break; } } } }
bool putBuffer() { Lock<Mutex> _(_dataAccessMutex); if(_inUseBuffers.size() >= MAX_BUFFER_COUNT) { logger(LOG_WARNING) << "USBBulkStreamer: Dropping a frame because of slow forward pipeline." << std::endl; _inUseBuffers.pop_front(); } auto f = _rawBuffers.get(); RawDataFramePtr &raw = *f; if(!raw || raw->data.size() != usbBuffer.size()) { raw = RawDataFramePtr(new RawDataFrame()); raw->data.resize(usbBuffer.size()); } memcpy(raw->data.data(), usbBuffer.data(), usbBuffer.size() - BULK_XFER_EXTRA_SIZE); raw->timestamp = _timer.getCurentRealTime(); // in micro seconds _inUseBuffers.push_back(f); _dataAvailableCondition.notify_all(); return true; }
void Inode::Close(int openMode, file_cookie* cookie) { TRACE("Inode %p::Close(openMode = %d)\n", this, openMode); MutexLocker locker(RequestLock()); // Notify all currently reading file descriptors ReadRequestList::Iterator iterator = fReadRequests.GetIterator(); while (ReadRequest* request = iterator.Next()) { if (request->Cookie() == cookie) request->Notify(B_FILE_ERROR); } if ((openMode & O_ACCMODE) == O_WRONLY && --fWriterCount == 0) NotifyEndClosed(true); if ((openMode & O_ACCMODE) == O_RDONLY || (openMode & O_ACCMODE) == O_RDWR) { if (--fReaderCount == 0) NotifyEndClosed(false); } if (fWriterCount == 0) { // Notify any still reading writers to stop // TODO: This only works reliable if there is only one writer - we could // do the same thing done for the read requests. fWriteCondition.NotifyAll(B_FILE_ERROR); } if (fReaderCount == 0 && fWriterCount == 0) { fActive = false; fBuffer.DeleteBuffer(); } }
/// Assign new task to the thread void assignNewTask(Threadpool::Task* task) { m_mutex.lock(); ANKI_ASSERT(m_task == nullptr && "Probably forgot to wait for tasks"); m_task = task; m_mutex.unlock(); m_condVar.notifyOne(); // Wake the thread }
Condition* ConditionVariable::load(QDomElement* root) { QDomElement elem = root->firstChildElement(); ConditionVariable* condition = new ConditionVariable(); while(!elem.isNull()) { if(elem.tagName().toLower().compare("name") == 0) { condition->setVarName( elem.text().toStdString() ); } else if(elem.tagName().toLower().compare("value") == 0) { condition->setTriggerValue( elem.text().toInt() ); } else if(elem.tagName().toLower().compare("trigger") == 0) { QString trigger = elem.text().toLower(); if( trigger.compare("equal") == 0) condition->setTrigger(Equal); else if( trigger.compare("nolongerequal") == 0) condition->setTrigger(NoLongerEqual); else if( trigger.compare("greaterthan") == 0) condition->setTrigger(GreaterThan); else if( trigger.compare("lessthan") == 0) condition->setTrigger(LessThan); } elem = elem.nextSiblingElement(); } return condition; }
inline void TriggerTimer::Cancel() { boost::lock_guard<Mutex> lock(m_mutex); if(!m_isPending) { return; } m_isPending = false; m_publisher.Push(Timer::Result::CANCELED); m_trigger.notify_all(); }
static void put_port_message(port_message* message) { size_t size = sizeof(port_message) + message->size; heap_free(sPortAllocator, message); atomic_add(&sTotalSpaceInUse, -size); sNoSpaceCondition.NotifyAll(); }
status_t DPCQueue::_Thread() { while (true) { InterruptsSpinLocker locker(fLock); // get the next pending callback DPCCallback* callback = fCallbacks.RemoveHead(); if (callback == NULL) { // nothing is pending -- wait unless the queue is already closed if (_IsClosed()) break; ConditionVariableEntry waitEntry; fPendingCallbacksCondition.Add(&waitEntry); locker.Unlock(); waitEntry.Wait(); continue; } callback->fInQueue = NULL; fCallbackInProgress = callback; // call the callback locker.Unlock(); callback->DoDPC(this); locker.Lock(); fCallbackInProgress = NULL; // wake up threads waiting for the callback to be done ConditionVariable* doneCondition = fCallbackDoneCondition; fCallbackDoneCondition = NULL; locker.Unlock(); if (doneCondition != NULL) doneCondition->NotifyAll(); } return B_OK; }
int WinMonitorData::BroadcastCondition( unsigned int cvid ) { int ret = -1; assert( hMutex != NULL ); ConditionVariableMap::iterator iter = cvmap.find( cvid ); if( iter != cvmap.end() ) { ConditionVariable* cv = cvmap[cvid]; assert( cv != NULL ); ret = cv->Broadcast(); } else { // bad cvid // TODO how to indicate the error? } return ret; }
static void increase_object_reserve(ObjectCache* cache) { MutexLocker locker(sMaintenanceLock); cache->maintenance_resize = true; if (!cache->maintenance_pending) { cache->maintenance_pending = true; sMaintenanceQueue.Add(cache); sMaintenanceCondition.NotifyAll(); } }
// Returns -1 for a fatal error, 0 on success, and 1 if the time given in // milliseconds has expired before the condition variable has been signalled. int WinMonitorData::TimedWaitOnCondition( unsigned int cvid, int milliseconds ) { int ret = -1; assert( hMutex != NULL ); ConditionVariableMap::iterator iter = cvmap.find( cvid ); if( iter != cvmap.end() ) { ConditionVariable* cv = cvmap[cvid]; assert( cv != NULL ); ret = cv->TimedWait(milliseconds); } else { // bad cvid // TODO how to indicate the error? assert(0); } return ret; }
void EnqueueTasks(const vector<Task *> &tasks) { #ifdef PBRT_USE_GRAND_CENTRAL_DISPATCH static bool oneThread = (getenv("PBRT_NTHREADS") && atoi(getenv("PBRT_NTHREADS")) == 1); for (u_int i = 0; i < tasks.size(); ++i) if (oneThread) dispatch_sync_f(gcdQueue, tasks[i], lRunTask); else dispatch_group_async_f(gcdGroup, gcdQueue, tasks[i], lRunTask); #else if (!threads) TasksInit(); { MutexLock lock(*taskQueueMutex); for (unsigned int i = 0; i < tasks.size(); ++i) taskQueue.push_back(tasks[i]); } tasksRunningCondition.Lock(); numUnfinishedTasks += tasks.size(); tasksRunningCondition.Unlock(); workerSemaphore.Post(tasks.size()); #endif }
void EnqueueTasks(const vector<Task *> &tasks) { if (PbrtOptions.nCores == 1) { for (unsigned int i = 0; i < tasks.size(); ++i) tasks[i]->Run(); return; } #ifdef PBRT_USE_GRAND_CENTRAL_DISPATCH for (uint32_t i = 0; i < tasks.size(); ++i) dispatch_group_async_f(gcdGroup, gcdQueue, tasks[i], lRunTask); #else if (!threads) TasksInit(); { MutexLock lock(*taskQueueMutex); for (unsigned int i = 0; i < tasks.size(); ++i) taskQueue.push_back(tasks[i]); } tasksRunningCondition.Lock(); numUnfinishedTasks += tasks.size(); tasksRunningCondition.Unlock(); workerSemaphore.Post(tasks.size()); #endif }
void slab_init_post_thread() { new(&sMaintenanceQueue) MaintenanceQueue; sMaintenanceCondition.Init(&sMaintenanceQueue, "object cache maintainer"); thread_id objectCacheResizer = spawn_kernel_thread(object_cache_maintainer, "object cache resizer", B_URGENT_PRIORITY, NULL); if (objectCacheResizer < 0) { panic("slab_init_post_thread(): failed to spawn object cache resizer " "thread\n"); return; } resume_thread(objectCacheResizer); }
/*! Notifies the low resource manager that a resource is lacking. If \a flags and \a timeout specify a timeout, the function will wait until the low resource manager has finished its next iteration of calling low resource handlers, or until the timeout occurs (whichever happens first). */ void low_resource(uint32 resource, uint64 requirements, uint32 flags, uint32 timeout) { // TODO: take requirements into account switch (resource) { case B_KERNEL_RESOURCE_PAGES: case B_KERNEL_RESOURCE_MEMORY: case B_KERNEL_RESOURCE_SEMAPHORES: case B_KERNEL_RESOURCE_ADDRESS_SPACE: break; } release_sem(sLowResourceWaitSem); if ((flags & B_RELATIVE_TIMEOUT) == 0 || timeout > 0) sLowResourceWaiterCondition.Wait(flags, timeout); }
PhysicalPageSlot* PhysicalPageSlotQueue::GetSlot() { InterruptsLocker locker; // wait for a free slot to turn up while (fSlots == NULL) { ConditionVariableEntry entry; fFreeSlotCondition.Add(&entry); locker.Unlock(); entry.Wait(); locker.Lock(); } PhysicalPageSlot* slot = fSlots; fSlots = slot->next; return slot; }
void PhysicalPageSlotQueue::GetSlots(PhysicalPageSlot*& slot1, PhysicalPageSlot*& slot2) { InterruptsLocker locker; // wait for two free slot to turn up while (fSlots == NULL || fSlots->next == NULL) { ConditionVariableEntry entry; fFreeSlotsCondition.Add(&entry); locker.Unlock(); entry.Wait(); locker.Lock(); } slot1 = fSlots; slot2 = slot1->next; fSlots = slot2->next; }
void Inode::Open(int openMode) { MutexLocker locker(RequestLock()); if ((openMode & O_ACCMODE) == O_WRONLY) fWriterCount++; if ((openMode & O_ACCMODE) == O_RDONLY || (openMode & O_ACCMODE) == O_RDWR) fReaderCount++; if (fReaderCount > 0 && fWriterCount > 0) { TRACE("Inode %p::Open(): fifo becomes active\n", this); fBuffer.CreateBuffer(); fActive = true; // notify all waiting writers that they can start if (fWriteSelectSyncPool) notify_select_event_pool(fWriteSelectSyncPool, B_SELECT_WRITE); fWriteCondition.NotifyAll(); } }