Exemplo n.º 1
0
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");
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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";
            }
        }
Exemplo n.º 5
0
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();
}
Exemplo n.º 7
0
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();
}
Exemplo n.º 8
0
/*
 * 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;
 }
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
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);
		}
	}
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
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;
			}
		}
	}
}
Exemplo n.º 14
0
  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;
  }
Exemplo n.º 15
0
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();
	}
}
Exemplo n.º 16
0
	/// 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
	}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
 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();
 }
Exemplo n.º 19
0
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();
}
Exemplo n.º 20
0
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;
}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
0
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();
	}
}
Exemplo n.º 23
0
// 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;
}
Exemplo n.º 24
0
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
}
Exemplo n.º 25
0
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
}
Exemplo n.º 26
0
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);
}
Exemplo n.º 27
0
/*!	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;
}
Exemplo n.º 30
0
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();
	}
}