⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prucv.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
     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;#ifndef XP_MAC    PR_LOG(_pr_clock_lm, PR_LOG_MAX,	   ("ExpireWaits: elapsed=%lld usec", elapsed));#endif    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 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -