BOOL ConsumeElement(int nThreadNum, int nRequestNum, HWND hWndLB) { // Get access to the queue to consume a new element AcquireSRWLockShared(&g_srwLock); // Fall asleep until there is something to read. // Check if, while it was asleep, // it was not decided that the thread should stop while (g_q.IsEmpty(nThreadNum) && !g_fShutdown) { // There was not a readable element AddText(hWndLB, TEXT("[%d] Nothing to process"), nThreadNum); // The queue is empty // --> Wait until a writer adds a new element to read // and come back with the lock acquired in shared mode SleepConditionVariableSRW(&g_cvReadyToConsume, &g_srwLock, INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED); } // When thread is exiting, the lock should be released for writer // and readers should be signaled through the condition variable if (g_fShutdown) { // Show that the current thread is exiting AddText(hWndLB, TEXT("[%d] bye bye"), nThreadNum); // Another writer thread might still be blocked on the lock // --> release it before exiting ReleaseSRWLockShared(&g_srwLock); // Notify other readers that it is time to exit // --> release readers WakeConditionVariable(&g_cvReadyToConsume); return(FALSE); } // Get the first new element CQueue::ELEMENT e; // Note: No need to test the return value since IsEmpty // returned FALSE g_q.GetNewElement(nThreadNum, e); // No need to keep the lock any longer ReleaseSRWLockShared(&g_srwLock); // Show result of consuming the element AddText(hWndLB, TEXT("[%d] Processing %d:%d"), nThreadNum, e.m_nThreadNum, e.m_nRequestNum); // A free slot is now available for writer threads to produce // --> wake up a writer thread WakeConditionVariable(&g_cvReadyToProduce); return(TRUE); }
void YabThreadWake(unsigned int id) { if (!thread_handle[id].thd) return; // Thread wasn't running in the first place WakeConditionVariable(&thread_handle[id].cond); }
inline void WinThreadCVImpl::wakeOne () { m_mutex.lock(); m_wakeups = CWT_MIN(m_wakeups + 1, m_waiters); WakeConditionVariable(& m_cond); m_mutex.unlock(); }
int tMPI_Thread_cond_signal(tMPI_Thread_cond_t *cond) { /* check whether the condition is initialized */ if (tMPI_Atomic_get( &(cond->initialized) ) == 0) { tMPI_Thread_cond_init_once(cond); } /* The condition variable is now guaranteed to be valid. */ #if 0 /* use this code once Vista is the minimum version required */ WakeConditionVariable( &(cond->cv) ); #else EnterCriticalSection(&(cond->condp->wtr_lock)); /* check if we're not still busy with a release. If we are, do nothing. */ if (cond->condp->Nwaiters > cond->condp->Nrelease) { cond->condp->Nrelease++; cond->condp->cycle++; if (!SetEvent(cond->condp->ev)) /* actually release the waiting threads */ { tMPI_Fatal_error(TMPI_FARGS,"Failed SetEvent, error code=%d", GetLastError()); return -1; } } LeaveCriticalSection(&(cond->condp->wtr_lock)); #endif return 0; }
lm_error lm_pulse(lm_monitor monitor) { if (!monitor || !monitor->ready) return lm_pointer; WakeConditionVariable(&monitor->cv); return lm_ok; }
DWORD WINAPI ProducerThreadProc (PVOID p) { ULONG ProducerId = (ULONG)(ULONG_PTR)p; while (true) { // Produce a new item. Sleep(rand() % PRODUCER_SLEEP_TIME_MS); ULONG Item = InterlockedIncrement(&LastItemProduced); EnterCriticalSection(&BufferLock); while (QueueSize == BUFFER_SIZE && StopRequested == FALSE) { // Buffer is full - sleep so consumers can get items. SleepConditionVariableCS(&BufferNotFull, &BufferLock, INFINITE); } if (StopRequested == TRUE) { LeaveCriticalSection(&BufferLock); break; } // Insert the item at the end of the queue and increment size. Buffer[(QueueStartOffset + QueueSize) % BUFFER_SIZE] = Item; ++QueueSize; ++TotalItemsProduced; printf("Producer %u: item %2d, queue size %2u\r\n", ProducerId, Item, QueueSize); LeaveCriticalSection(&BufferLock); // If a consumer is waiting, wake it. WakeConditionVariable(&BufferNotEmpty); } printf("Producer %u exiting\r\n", ProducerId); return 0; }
void SkCondVar::signal() { #ifdef SK_USE_POSIX_THREADS pthread_cond_signal(&fCond); #elif defined(SK_BUILD_FOR_WIN32) WakeConditionVariable(&fCondition); #endif }
DWORD WINAPI ConsumerThreadProc (PVOID p) { ULONG ConsumerId = (ULONG)(ULONG_PTR)p; while (true) { EnterCriticalSection(&BufferLock); while (QueueSize == 0 && StopRequested == FALSE) { // Buffer is empty - sleep so producers can create items. SleepConditionVariableCS(&BufferNotEmpty, &BufferLock, INFINITE); } if (StopRequested == TRUE && QueueSize == 0) { LeaveCriticalSection(&BufferLock); break; } // Consume the first available item. LONG Item = Buffer[QueueStartOffset]; --QueueSize; ++QueueStartOffset; ++TotalItemsConsumed; if (QueueStartOffset == BUFFER_SIZE) { QueueStartOffset = 0; } printf("Consumer %u: item %2d, queue size %2u\r\n", ConsumerId, Item, QueueSize); LeaveCriticalSection(&BufferLock); // If a producer is waiting, wake it. WakeConditionVariable(&BufferNotFull); // Simulate processing of the item. Sleep(rand() % CONSUMER_SLEEP_TIME_MS); } printf("Consumer %u exiting\r\n", ConsumerId); return 0; }
/** @Status Caveat @Notes Error return codes ignored. */ extern "C" int pthread_cond_signal(pthread_cond_t* cond) { if (*((uint32_t*)cond) == (uint32_t)PTHREAD_COND_INITIALIZER) { pthread_cond_init(cond, 0); } WakeConditionVariable((CONDITION_VARIABLE*)*cond); return 0; }
void C_CondVar::M_SignalOne() { #ifdef _WIN32 WakeConditionVariable(&m_Cond); #else pthread_cond_signal(&m_Cond); #endif }
int condvar_wake_one(struct condvar_handle *condvar) { struct condvar_priv *priv = (struct condvar_priv *)condvar->priv; WakeConditionVariable(&priv->cond); return 0; }
void CondVar::WakeOne() { #ifdef WIN32 WakeConditionVariable(&mCondVar); #else #endif }
bool WindowsCondVar::notify(bool lock) { if (lock) ownLock(); WakeConditionVariable(&_condvar); if (lock) ownUnlock(); return (true); }
void ConditionVariableImpl::Signal() { #if NAZARA_CORE_WINDOWS_VISTA WakeConditionVariable(&m_cv); #else if (m_count > 0) SetEvent(m_events[SIGNAL]); #endif }
void Conditional::Signal() { //printf("Signal(%s) start\n", mName.GetCString()); #if defined(FastOSWindows) WakeConditionVariable(&mConditionVariable->cv); #elif defined(FastOSUnixLike) pthread_cond_signal(&mConditionVariable->cv); #endif //printf("Signal(%s) end\n", mName.GetCString()); }
void vp_os_cond_signal(vp_os_cond_t *cond) { #if defined USE_WINDOWS_CONDITION_VARIABLES WakeConditionVariable(&cond->cond); #elif defined USE_PTHREAD_FOR_WIN32 pthread_cond_signal(&cond->cond); #endif }
int __bctbx_WIN_cond_signal(bctbx_cond_t * hCond) { #ifdef BCTBX_WINDOWS_DESKTOP SetEvent(*hCond); #else WakeConditionVariable(hCond); #endif return 0; }
void Condition::signal() { #if defined(OS_WINDOWS_VISTA_DISABLED) WakeConditionVariable(&cond); #elif defined(OS_WINDOWS) PulseEvent(cond); #elif defined(OS_UNIX) pthread_cond_signal(&cond); #endif }
// 7.25.3.4 int cnd_signal(cnd_t *cond) { if (!cond) return thrd_error; #ifdef EMULATED_THREADS_USE_NATIVE_CV WakeConditionVariable(&cond->condvar); #else impl_cond_do_signal(cond, 0); #endif return thrd_success; }
void r_cond_signal (RCond * cond) { #if defined (R_OS_WIN32) WakeConditionVariable ((PCONDITION_VARIABLE)*cond); #elif defined (HAVE_PTHREAD_H) pthread_cond_signal ((pthread_cond_t*)*cond); #else (void) cond; #endif }
teUtilsStatus eUtils_QueueQueue(tsUtilsQueue *psQueue, void *pvData) { tsQueuePrivate *psQueuePrivate = (tsQueuePrivate*)psQueue->pvPriv; DBG_vPrintf(DBG_QUEUE, "Queue %p: Queue %p\n", psQueue, pvData); #ifndef WIN32 pthread_mutex_lock (&psQueuePrivate->mMutex); #else EnterCriticalSection (&psQueuePrivate->hMutex); #endif /* WIN32 */ DBG_vPrintf(DBG_QUEUE, "Got mutex on queue %p (size = %d)\n", psQueue, psQueuePrivate->u32Size); if (psQueuePrivate->iFlags & UTILS_QUEUE_NONBLOCK_INPUT) { // Check if buffer is full and return if so. if (psQueuePrivate->u32Size == psQueuePrivate->u32Capacity) { DBG_vPrintf(DBG_QUEUE, "Queue full, could not enqueue entry\n"); #ifndef WIN32 pthread_mutex_unlock (&psQueuePrivate->mMutex); #else LeaveCriticalSection (&psQueuePrivate->hMutex); #endif /* WIN32 */ return E_UTILS_ERROR_BLOCK; } } else { // Block until space is available while (psQueuePrivate->u32Size == psQueuePrivate->u32Capacity) #ifndef WIN32 pthread_cond_wait (&psQueuePrivate->cond_space_available, &psQueuePrivate->mMutex); #else SleepConditionVariableCS(&psQueuePrivate->hSpaceAvailable, &psQueuePrivate->hMutex, INFINITE); #endif /* WIN32 */ } psQueuePrivate->apvBuffer[psQueuePrivate->u32In] = pvData; psQueuePrivate->u32Size++; psQueuePrivate->u32In = (psQueuePrivate->u32In+1) % psQueuePrivate->u32Capacity; #ifndef WIN32 pthread_mutex_unlock (&psQueuePrivate->mMutex); pthread_cond_broadcast (&psQueuePrivate->cond_data_available); #else LeaveCriticalSection (&psQueuePrivate->hMutex); WakeConditionVariable (&psQueuePrivate->hDataAvailable); #endif /* WIN32 */ DBG_vPrintf(DBG_QUEUE, "Queue %p: Queued %p\n", psQueue, pvData); return E_UTILS_OK; }
teUtilsStatus eUtils_QueueDequeue(tsUtilsQueue *psQueue, void **ppvData) { tsQueuePrivate *psQueuePrivate = (tsQueuePrivate*)psQueue->pvPriv; DBG_vPrintf(DBG_QUEUE, "Queue %p: Dequeue\n", psQueue); #ifndef WIN32 pthread_mutex_lock (&psQueuePrivate->mMutex); #else EnterCriticalSection (&psQueuePrivate->hMutex); #endif /* WIN32 */ DBG_vPrintf(DBG_QUEUE, "Got mutex on queue %p (size=%d)\n", psQueue, psQueuePrivate->u32Size); if (psQueuePrivate->iFlags & UTILS_QUEUE_NONBLOCK_OUTPUT) { // Check if buffer is empty and return if so. if (psQueuePrivate->u32Size == 0) { DBG_vPrintf(DBG_QUEUE, "Queue empty\n"); #ifndef WIN32 pthread_mutex_unlock (&psQueuePrivate->mMutex); #else LeaveCriticalSection (&psQueuePrivate->hMutex); #endif /* WIN32 */ return E_UTILS_ERROR_BLOCK; } } else { // Wait for data to become available while (psQueuePrivate->u32Size == 0) #ifndef WIN32 pthread_cond_wait (&psQueuePrivate->cond_data_available, &psQueuePrivate->mMutex); #else SleepConditionVariableCS(&psQueuePrivate->hDataAvailable, &psQueuePrivate->hMutex, INFINITE); #endif /* WIN32 */ } *ppvData = psQueuePrivate->apvBuffer[psQueuePrivate->u32Out]; psQueuePrivate->u32Size--; psQueuePrivate->u32Out = (psQueuePrivate->u32Out + 1) % psQueuePrivate->u32Capacity; #ifndef WIN32 pthread_mutex_unlock (&psQueuePrivate->mMutex); pthread_cond_broadcast (&psQueuePrivate->cond_space_available); #else LeaveCriticalSection (&psQueuePrivate->hMutex); WakeConditionVariable (&psQueuePrivate->hSpaceAvailable); #endif /* WIN32 */ DBG_vPrintf(DBG_QUEUE, "Queue %p: Dequeued %p\n", psQueue, *ppvData); return E_UTILS_OK; }
EXEC_RETURN condition_WakeThread(CONDITION* condition){ #if defined(WIN32) || defined(_WIN64) WakeConditionVariable(condition); return EXEC_SUCCESS; #else int res = pthread_cond_signal(condition); if(res){ errno = res; return EXEC_ERROR; } return EXEC_SUCCESS; #endif }
void NzConditionVariableImpl::Signal() { #if NAZARA_CORE_WINDOWS_VISTA WakeConditionVariable(&m_cv); #else // Avoid race conditions. EnterCriticalSection(&m_countLock); bool haveWaiters = (m_count > 0); LeaveCriticalSection(&m_countLock); if (haveWaiters) SetEvent(m_events[SIGNAL]); #endif }
void os_cond_signal(struct OsCond *cond, struct OsMutex *locked_mutex) { #if defined(GENESIS_OS_WINDOWS) if (locked_mutex) { WakeConditionVariable(&cond->id); } else { EnterCriticalSection(&cond->default_cs_id); WakeConditionVariable(&cond->id); LeaveCriticalSection(&cond->default_cs_id); } #elif defined(GENESIS_OS_KQUEUE) struct kevent kev; struct timespec timeout = { 0, 0 }; memset(&kev, 0, sizeof(kev)); kev.ident = notify_ident; kev.filter = EVFILT_USER; kev.fflags = NOTE_TRIGGER; if (kevent(cond->kq_id, &kev, 1, NULL, 0, &timeout) == -1) { if (errno == EINTR) return; if (errno == ENOENT) return; assert(0); // kevent signal error } #else if (locked_mutex) { assert_no_err(pthread_cond_signal(&cond->id)); } else { assert_no_err(pthread_mutex_lock(&cond->default_mutex_id)); assert_no_err(pthread_cond_signal(&cond->id)); assert_no_err(pthread_mutex_unlock(&cond->default_mutex_id)); } #endif }
static int pthread_cond_signal(pthread_cond_t* const condition) { int ok = 1; #ifdef USE_WINDOWS_CONDITION_VARIABLE WakeConditionVariable(condition); #else if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) { // a thread is waiting in pthread_cond_wait: allow it to be notified ok = SetEvent(condition->signal_event_); // wait until the event is consumed so the signaler cannot consume // the event via its own pthread_cond_wait. ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) != WAIT_OBJECT_0); } #endif return !ok; }
DWORD QueuePut (QUEUE_OBJECT *q, PVOID msg, DWORD msize, DWORD MaxWait) { AcquireSRWLockExclusive (&q->qGuard); if (q->msgArray == NULL) return 1; /* Queue has been destroyed */ while (QueueFull (q)) { if (!SleepConditionVariableSRW(&q->qNf, &q->qGuard, INFINITE, 0)) ReportError(_T("QueuePut failed. SleepConditionVariableCS."), 1, TRUE); } /* Put the message in the queue */ QueueInsert (q, msg, msize); /* Signal that the queue is not empty as we've inserted a message */ WakeConditionVariable (&q->qNe); ReleaseSRWLockExclusive (&q->qGuard); return 0; }
DWORD QueueGet (QUEUE_OBJECT *q, PVOID msg, DWORD msize, DWORD MaxWait) { AcquireSRWLockExclusive (&q->qGuard); if (q->msgArray == NULL) return 1; /* Queue has been destroyed */ while (QueueEmpty (q)) { if (!SleepConditionVariableSRW (&q->qNe, &q->qGuard, INFINITE, 0)) ReportError(_T("QueueGet failed. SleepConditionVariableCS."), 1, TRUE); } /* remove the message from the queue */ QueueRemove (q, msg, msize); /* Signal that the queue is not full as we've removed a message */ WakeConditionVariable (&q->qNf); ReleaseSRWLockExclusive (&q->qGuard); return 0; }
void Buffer::add(void *data, size_t size, int sampleRate, int channels) { Gentry *e = new Gentry; e->data = data; e->size = size; e->sampleRate = sampleRate; e->channels = channels; { LockedCS lock(bufferLock); // Yes, this is spinlock. See the class comment. while (entries >= MAX_ENTRIES) lock.dropAndReacquire(); entry[(ptr + entries) % MAX_ENTRIES] = e; ++entries; } WakeConditionVariable(&bufferNotEmpty); }
PLATAPI void plat_cv_notify_one(plat_thread_cv_t* cv) { WakeConditionVariable(&cv->tcv_cond_var); }