Index: mozilla/nsprpub/pr/src/threads/combined/prucv.c |
=================================================================== |
--- mozilla/nsprpub/pr/src/threads/combined/prucv.c (revision 191424) |
+++ mozilla/nsprpub/pr/src/threads/combined/prucv.c (working copy) |
@@ -1,645 +0,0 @@ |
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
- |
- |
-#include "primpl.h" |
-#include "prinrval.h" |
-#include "prtypes.h" |
- |
-#if defined(WIN95) |
-/* |
-** Some local variables report warnings on Win95 because the code paths |
-** using them are conditioned on HAVE_CUSTOME_USER_THREADS. |
-** The pragma suppresses the warning. |
-** |
-*/ |
-#pragma warning(disable : 4101) |
-#endif |
- |
- |
-/* |
-** Notify one thread that it has finished waiting on a condition variable |
-** Caller must hold the _PR_CVAR_LOCK(cv) |
-*/ |
-PRBool _PR_NotifyThread (PRThread *thread, PRThread *me) |
-{ |
- PRBool rv; |
- |
- PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); |
- |
- _PR_THREAD_LOCK(thread); |
- PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); |
- if ( !_PR_IS_NATIVE_THREAD(thread) ) { |
- if (thread->wait.cvar != NULL) { |
- thread->wait.cvar = NULL; |
- |
- _PR_SLEEPQ_LOCK(thread->cpu); |
- /* The notify and timeout can collide; in which case both may |
- * attempt to delete from the sleepQ; only let one do it. |
- */ |
- if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ)) |
- _PR_DEL_SLEEPQ(thread, PR_TRUE); |
- _PR_SLEEPQ_UNLOCK(thread->cpu); |
- |
- if (thread->flags & _PR_SUSPENDING) { |
- /* |
- * set thread state to SUSPENDED; a Resume operation |
- * on the thread will move it to the runQ |
- */ |
- thread->state = _PR_SUSPENDED; |
- _PR_MISCQ_LOCK(thread->cpu); |
- _PR_ADD_SUSPENDQ(thread, thread->cpu); |
- _PR_MISCQ_UNLOCK(thread->cpu); |
- _PR_THREAD_UNLOCK(thread); |
- } else { |
- /* Make thread runnable */ |
- thread->state = _PR_RUNNABLE; |
- _PR_THREAD_UNLOCK(thread); |
- |
- _PR_AddThreadToRunQ(me, thread); |
- _PR_MD_WAKEUP_WAITER(thread); |
- } |
- |
- rv = PR_TRUE; |
- } else { |
- /* Thread has already been notified */ |
- _PR_THREAD_UNLOCK(thread); |
- rv = PR_FALSE; |
- } |
- } else { /* If the thread is a native thread */ |
- if (thread->wait.cvar) { |
- thread->wait.cvar = NULL; |
- |
- if (thread->flags & _PR_SUSPENDING) { |
- /* |
- * set thread state to SUSPENDED; a Resume operation |
- * on the thread will enable the thread to run |
- */ |
- thread->state = _PR_SUSPENDED; |
- } else |
- thread->state = _PR_RUNNING; |
- _PR_THREAD_UNLOCK(thread); |
- _PR_MD_WAKEUP_WAITER(thread); |
- rv = PR_TRUE; |
- } else { |
- _PR_THREAD_UNLOCK(thread); |
- rv = PR_FALSE; |
- } |
- } |
- |
- return rv; |
-} |
- |
-/* |
- * Notify thread waiting on cvar; called when thread is interrupted |
- * The thread lock is held on entry and released before return |
- */ |
-void _PR_NotifyLockedThread (PRThread *thread) |
-{ |
- PRThread *me = _PR_MD_CURRENT_THREAD(); |
- PRCondVar *cvar; |
- PRThreadPriority pri; |
- |
- if ( !_PR_IS_NATIVE_THREAD(me)) |
- PR_ASSERT(_PR_MD_GET_INTSOFF() != 0); |
- |
- cvar = thread->wait.cvar; |
- thread->wait.cvar = NULL; |
- _PR_THREAD_UNLOCK(thread); |
- |
- _PR_CVAR_LOCK(cvar); |
- _PR_THREAD_LOCK(thread); |
- |
- if (!_PR_IS_NATIVE_THREAD(thread)) { |
- _PR_SLEEPQ_LOCK(thread->cpu); |
- /* The notify and timeout can collide; in which case both may |
- * attempt to delete from the sleepQ; only let one do it. |
- */ |
- if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ)) |
- _PR_DEL_SLEEPQ(thread, PR_TRUE); |
- _PR_SLEEPQ_UNLOCK(thread->cpu); |
- |
- /* Make thread runnable */ |
- pri = thread->priority; |
- thread->state = _PR_RUNNABLE; |
- |
- PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); |
- |
- _PR_AddThreadToRunQ(me, thread); |
- _PR_THREAD_UNLOCK(thread); |
- |
- _PR_MD_WAKEUP_WAITER(thread); |
- } else { |
- if (thread->flags & _PR_SUSPENDING) { |
- /* |
- * set thread state to SUSPENDED; a Resume operation |
- * on the thread will enable the thread to run |
- */ |
- thread->state = _PR_SUSPENDED; |
- } else |
- thread->state = _PR_RUNNING; |
- _PR_THREAD_UNLOCK(thread); |
- _PR_MD_WAKEUP_WAITER(thread); |
- } |
- |
- _PR_CVAR_UNLOCK(cvar); |
- return; |
-} |
- |
-/* |
-** Make the given thread wait for the given condition variable |
-*/ |
-PRStatus _PR_WaitCondVar( |
- PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout) |
-{ |
- PRIntn is; |
- PRStatus rv = PR_SUCCESS; |
- |
- PR_ASSERT(thread == _PR_MD_CURRENT_THREAD()); |
- PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); |
- |
-#ifdef _PR_GLOBAL_THREADS_ONLY |
- if (_PR_PENDING_INTERRUPT(thread)) { |
- PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); |
- thread->flags &= ~_PR_INTERRUPT; |
- return PR_FAILURE; |
- } |
- |
- thread->wait.cvar = cvar; |
- lock->owner = NULL; |
- _PR_MD_WAIT_CV(&cvar->md,&lock->ilock, timeout); |
- thread->wait.cvar = NULL; |
- lock->owner = thread; |
- if (_PR_PENDING_INTERRUPT(thread)) { |
- PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); |
- thread->flags &= ~_PR_INTERRUPT; |
- return PR_FAILURE; |
- } |
- |
- return PR_SUCCESS; |
-#else /* _PR_GLOBAL_THREADS_ONLY */ |
- |
- if ( !_PR_IS_NATIVE_THREAD(thread)) |
- _PR_INTSOFF(is); |
- |
- _PR_CVAR_LOCK(cvar); |
- _PR_THREAD_LOCK(thread); |
- |
- if (_PR_PENDING_INTERRUPT(thread)) { |
- PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); |
- thread->flags &= ~_PR_INTERRUPT; |
- _PR_CVAR_UNLOCK(cvar); |
- _PR_THREAD_UNLOCK(thread); |
- if ( !_PR_IS_NATIVE_THREAD(thread)) |
- _PR_INTSON(is); |
- return PR_FAILURE; |
- } |
- |
- thread->state = _PR_COND_WAIT; |
- thread->wait.cvar = cvar; |
- |
- /* |
- ** Put the caller thread on the condition variable's wait Q |
- */ |
- PR_APPEND_LINK(&thread->waitQLinks, &cvar->condQ); |
- |
- /* Note- for global scope threads, we don't put them on the |
- * global sleepQ, so each global thread must put itself |
- * to sleep only for the time it wants to. |
- */ |
- if ( !_PR_IS_NATIVE_THREAD(thread) ) { |
- _PR_SLEEPQ_LOCK(thread->cpu); |
- _PR_ADD_SLEEPQ(thread, timeout); |
- _PR_SLEEPQ_UNLOCK(thread->cpu); |
- } |
- _PR_CVAR_UNLOCK(cvar); |
- _PR_THREAD_UNLOCK(thread); |
- |
- /* |
- ** Release lock protecting the condition variable and thereby giving time |
- ** to the next thread which can potentially notify on the condition variable |
- */ |
- PR_Unlock(lock); |
- |
- PR_LOG(_pr_cvar_lm, PR_LOG_MIN, |
- ("PR_Wait: cvar=%p waiting for %d", cvar, timeout)); |
- |
- rv = _PR_MD_WAIT(thread, timeout); |
- |
- _PR_CVAR_LOCK(cvar); |
- PR_REMOVE_LINK(&thread->waitQLinks); |
- _PR_CVAR_UNLOCK(cvar); |
- |
- PR_LOG(_pr_cvar_lm, PR_LOG_MIN, |
- ("PR_Wait: cvar=%p done waiting", cvar)); |
- |
- if ( !_PR_IS_NATIVE_THREAD(thread)) |
- _PR_INTSON(is); |
- |
- /* Acquire lock again that we had just relinquished */ |
- PR_Lock(lock); |
- |
- if (_PR_PENDING_INTERRUPT(thread)) { |
- PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); |
- thread->flags &= ~_PR_INTERRUPT; |
- return PR_FAILURE; |
- } |
- |
- return rv; |
-#endif /* _PR_GLOBAL_THREADS_ONLY */ |
-} |
- |
-void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me) |
-{ |
-#ifdef _PR_GLOBAL_THREADS_ONLY |
- _PR_MD_NOTIFY_CV(&cvar->md, &cvar->lock->ilock); |
-#else /* _PR_GLOBAL_THREADS_ONLY */ |
- |
- PRCList *q; |
- PRIntn is; |
- |
- if ( !_PR_IS_NATIVE_THREAD(me)) |
- _PR_INTSOFF(is); |
- PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); |
- |
- _PR_CVAR_LOCK(cvar); |
- q = cvar->condQ.next; |
- while (q != &cvar->condQ) { |
- PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("_PR_NotifyCondVar: cvar=%p", cvar)); |
- if (_PR_THREAD_CONDQ_PTR(q)->wait.cvar) { |
- if (_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me) == PR_TRUE) |
- break; |
- } |
- q = q->next; |
- } |
- _PR_CVAR_UNLOCK(cvar); |
- |
- if ( !_PR_IS_NATIVE_THREAD(me)) |
- _PR_INTSON(is); |
- |
-#endif /* _PR_GLOBAL_THREADS_ONLY */ |
-} |
- |
-/* |
-** Cndition variable debugging log info. |
-*/ |
-PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen) |
-{ |
- PRUint32 nb; |
- |
- if (cvar->lock->owner) { |
- nb = PR_snprintf(buf, buflen, "[%p] owner=%ld[%p]", |
- cvar, cvar->lock->owner->id, cvar->lock->owner); |
- } else { |
- nb = PR_snprintf(buf, buflen, "[%p]", cvar); |
- } |
- return nb; |
-} |
- |
-/* |
-** Expire condition variable waits that are ready to expire. "now" is the current |
-** time. |
-*/ |
-void _PR_ClockInterrupt(void) |
-{ |
- PRThread *thread, *me = _PR_MD_CURRENT_THREAD(); |
- _PRCPU *cpu = me->cpu; |
- PRIntervalTime elapsed, now; |
- |
- PR_ASSERT(_PR_MD_GET_INTSOFF() != 0); |
- /* Figure out how much time elapsed since the last clock tick */ |
- now = PR_IntervalNow(); |
- elapsed = now - cpu->last_clock; |
- cpu->last_clock = now; |
- |
- PR_LOG(_pr_clock_lm, PR_LOG_MAX, |
- ("ExpireWaits: elapsed=%lld usec", elapsed)); |
- |
- while(1) { |
- _PR_SLEEPQ_LOCK(cpu); |
- if (_PR_SLEEPQ(cpu).next == &_PR_SLEEPQ(cpu)) { |
- _PR_SLEEPQ_UNLOCK(cpu); |
- break; |
- } |
- |
- thread = _PR_THREAD_PTR(_PR_SLEEPQ(cpu).next); |
- PR_ASSERT(thread->cpu == cpu); |
- |
- if (elapsed < thread->sleep) { |
- thread->sleep -= elapsed; |
- _PR_SLEEPQMAX(thread->cpu) -= elapsed; |
- _PR_SLEEPQ_UNLOCK(cpu); |
- break; |
- } |
- _PR_SLEEPQ_UNLOCK(cpu); |
- |
- PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread)); |
- |
- _PR_THREAD_LOCK(thread); |
- |
- if (thread->cpu != cpu) { |
- /* |
- ** The thread was switched to another CPU |
- ** between the time we unlocked the sleep |
- ** queue and the time we acquired the thread |
- ** lock, so it is none of our business now. |
- */ |
- _PR_THREAD_UNLOCK(thread); |
- continue; |
- } |
- |
- /* |
- ** Consume this sleeper's amount of elapsed time from the elapsed |
- ** time value. The next remaining piece of elapsed time will be |
- ** available for the next sleeping thread's timer. |
- */ |
- _PR_SLEEPQ_LOCK(cpu); |
- PR_ASSERT(!(thread->flags & _PR_ON_PAUSEQ)); |
- if (thread->flags & _PR_ON_SLEEPQ) { |
- _PR_DEL_SLEEPQ(thread, PR_FALSE); |
- elapsed -= thread->sleep; |
- _PR_SLEEPQ_UNLOCK(cpu); |
- } else { |
- /* Thread was already handled; Go get another one */ |
- _PR_SLEEPQ_UNLOCK(cpu); |
- _PR_THREAD_UNLOCK(thread); |
- continue; |
- } |
- |
- /* Notify the thread waiting on the condition variable */ |
- if (thread->flags & _PR_SUSPENDING) { |
- PR_ASSERT((thread->state == _PR_IO_WAIT) || |
- (thread->state == _PR_COND_WAIT)); |
- /* |
- ** Thread is suspended and its condition timeout |
- ** expired. Transfer thread from sleepQ to suspendQ. |
- */ |
- thread->wait.cvar = NULL; |
- _PR_MISCQ_LOCK(cpu); |
- thread->state = _PR_SUSPENDED; |
- _PR_ADD_SUSPENDQ(thread, cpu); |
- _PR_MISCQ_UNLOCK(cpu); |
- } else { |
- if (thread->wait.cvar) { |
- PRThreadPriority pri; |
- |
- /* Do work very similar to what _PR_NotifyThread does */ |
- PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) ); |
- |
- /* Make thread runnable */ |
- pri = thread->priority; |
- thread->state = _PR_RUNNABLE; |
- PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); |
- |
- PR_ASSERT(thread->cpu == cpu); |
- _PR_RUNQ_LOCK(cpu); |
- _PR_ADD_RUNQ(thread, cpu, pri); |
- _PR_RUNQ_UNLOCK(cpu); |
- |
- if (pri > me->priority) |
- _PR_SET_RESCHED_FLAG(); |
- |
- thread->wait.cvar = NULL; |
- |
- _PR_MD_WAKEUP_WAITER(thread); |
- |
- } else if (thread->io_pending == PR_TRUE) { |
- /* Need to put IO sleeper back on runq */ |
- int pri = thread->priority; |
- |
- thread->io_suspended = PR_TRUE; |
-#ifdef WINNT |
- /* |
- * For NT, record the cpu on which I/O was issued |
- * I/O cancellation is done on the same cpu |
- */ |
- thread->md.thr_bound_cpu = cpu; |
-#endif |
- |
- PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD)); |
- PR_ASSERT(thread->cpu == cpu); |
- thread->state = _PR_RUNNABLE; |
- _PR_RUNQ_LOCK(cpu); |
- _PR_ADD_RUNQ(thread, cpu, pri); |
- _PR_RUNQ_UNLOCK(cpu); |
- } |
- } |
- _PR_THREAD_UNLOCK(thread); |
- } |
-} |
- |
-/************************************************************************/ |
- |
-/* |
-** Create a new condition variable. |
-** "lock" is the lock to use with the condition variable. |
-** |
-** Condition variables are synchronization objects that threads can use |
-** to wait for some condition to occur. |
-** |
-** This may fail if memory is tight or if some operating system resource |
-** is low. |
-*/ |
-PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock) |
-{ |
- PRCondVar *cvar; |
- |
- PR_ASSERT(lock != NULL); |
- |
- cvar = PR_NEWZAP(PRCondVar); |
- if (cvar) { |
-#ifdef _PR_GLOBAL_THREADS_ONLY |
- if(_PR_MD_NEW_CV(&cvar->md)) { |
- PR_DELETE(cvar); |
- PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); |
- return NULL; |
- } |
-#endif |
- if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE) { |
- PR_DELETE(cvar); |
- PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); |
- return NULL; |
- } |
- cvar->lock = lock; |
- PR_INIT_CLIST(&cvar->condQ); |
- |
- } else { |
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); |
- } |
- return cvar; |
-} |
- |
-/* |
-** Destroy a condition variable. There must be no thread |
-** waiting on the condvar. The caller is responsible for guaranteeing |
-** that the condvar is no longer in use. |
-** |
-*/ |
-PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar) |
-{ |
- PR_ASSERT(cvar->condQ.next == &cvar->condQ); |
- |
-#ifdef _PR_GLOBAL_THREADS_ONLY |
- _PR_MD_FREE_CV(&cvar->md); |
-#endif |
- _PR_MD_FREE_LOCK(&(cvar->ilock)); |
- |
- PR_DELETE(cvar); |
-} |
- |
-/* |
-** Wait for a notify on the condition variable. Sleep for "tiemout" amount |
-** of ticks (if "timeout" is zero then the sleep is indefinite). While |
-** the thread is waiting it unlocks lock. When the wait has |
-** finished the thread regains control of the condition variable after |
-** locking the associated lock. |
-** |
-** The thread waiting on the condvar will be resumed when the condvar is |
-** notified (assuming the thread is the next in line to receive the |
-** notify) or when the timeout elapses. |
-** |
-** Returns PR_FAILURE if the caller has not locked the lock associated |
-** with the condition variable or the thread has been interrupted. |
-*/ |
-extern PRThread *suspendAllThread; |
-PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout) |
-{ |
- PRThread *me = _PR_MD_CURRENT_THREAD(); |
- |
- PR_ASSERT(cvar->lock->owner == me); |
- PR_ASSERT(me != suspendAllThread); |
- if (cvar->lock->owner != me) return PR_FAILURE; |
- |
- return _PR_WaitCondVar(me, cvar, cvar->lock, timeout); |
-} |
- |
-/* |
-** Notify the highest priority thread waiting on the condition |
-** variable. If a thread is waiting on the condition variable (using |
-** PR_Wait) then it is awakened and begins waiting on the lock. |
-*/ |
-PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar) |
-{ |
- PRThread *me = _PR_MD_CURRENT_THREAD(); |
- |
- PR_ASSERT(cvar->lock->owner == me); |
- PR_ASSERT(me != suspendAllThread); |
- if (cvar->lock->owner != me) return PR_FAILURE; |
- |
- _PR_NotifyCondVar(cvar, me); |
- return PR_SUCCESS; |
-} |
- |
-/* |
-** Notify all of the threads waiting on the condition variable. All of |
-** threads are notified in turn. The highest priority thread will |
-** probably acquire the lock. |
-*/ |
-PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar) |
-{ |
- PRCList *q; |
- PRIntn is; |
- PRThread *me = _PR_MD_CURRENT_THREAD(); |
- |
- PR_ASSERT(cvar->lock->owner == me); |
- if (cvar->lock->owner != me) return PR_FAILURE; |
- |
-#ifdef _PR_GLOBAL_THREADS_ONLY |
- _PR_MD_NOTIFYALL_CV(&cvar->md, &cvar->lock->ilock); |
- return PR_SUCCESS; |
-#else /* _PR_GLOBAL_THREADS_ONLY */ |
- if ( !_PR_IS_NATIVE_THREAD(me)) |
- _PR_INTSOFF(is); |
- _PR_CVAR_LOCK(cvar); |
- q = cvar->condQ.next; |
- while (q != &cvar->condQ) { |
- PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)); |
- _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me); |
- q = q->next; |
- } |
- _PR_CVAR_UNLOCK(cvar); |
- if (!_PR_IS_NATIVE_THREAD(me)) |
- _PR_INTSON(is); |
- |
- return PR_SUCCESS; |
-#endif /* _PR_GLOBAL_THREADS_ONLY */ |
-} |
- |
- |
-/*********************************************************************/ |
-/*********************************************************************/ |
-/********************ROUTINES FOR DCE EMULATION***********************/ |
-/*********************************************************************/ |
-/*********************************************************************/ |
-#include "prpdce.h" |
- |
-PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void) |
-{ |
- PRCondVar *cvar = PR_NEWZAP(PRCondVar); |
- if (NULL != cvar) |
- { |
- if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE) |
- { |
- PR_DELETE(cvar); cvar = NULL; |
- } |
- else |
- { |
- PR_INIT_CLIST(&cvar->condQ); |
- cvar->lock = _PR_NAKED_CV_LOCK; |
- } |
- |
- } |
- return cvar; |
-} |
- |
-PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar) |
-{ |
- PR_ASSERT(cvar->condQ.next == &cvar->condQ); |
- PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); |
- |
- _PR_MD_FREE_LOCK(&(cvar->ilock)); |
- |
- PR_DELETE(cvar); |
-} |
- |
-PR_IMPLEMENT(PRStatus) PRP_NakedWait( |
- PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout) |
-{ |
- PRThread *me = _PR_MD_CURRENT_THREAD(); |
- PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); |
- return _PR_WaitCondVar(me, cvar, lock, timeout); |
-} /* PRP_NakedWait */ |
- |
-PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar) |
-{ |
- PRThread *me = _PR_MD_CURRENT_THREAD(); |
- PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); |
- |
- _PR_NotifyCondVar(cvar, me); |
- |
- return PR_SUCCESS; |
-} /* PRP_NakedNotify */ |
- |
-PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar) |
-{ |
- PRCList *q; |
- PRIntn is; |
- PRThread *me = _PR_MD_CURRENT_THREAD(); |
- PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock); |
- |
- if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is); |
- _PR_MD_LOCK( &(cvar->ilock) ); |
- q = cvar->condQ.next; |
- while (q != &cvar->condQ) { |
- PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar)); |
- _PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me); |
- q = q->next; |
- } |
- _PR_MD_UNLOCK( &(cvar->ilock) ); |
- if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is); |
- |
- return PR_SUCCESS; |
-} /* PRP_NakedBroadcast */ |
- |