| Index: mozilla/nsprpub/pr/src/threads/combined/prulock.c | 
| =================================================================== | 
| --- mozilla/nsprpub/pr/src/threads/combined/prulock.c	(revision 191424) | 
| +++ mozilla/nsprpub/pr/src/threads/combined/prulock.c	(working copy) | 
| @@ -1,433 +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" | 
| - | 
| -#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 | 
| - | 
| - | 
| -void _PR_InitLocks(void) | 
| -{ | 
| -	_PR_MD_INIT_LOCKS(); | 
| -} | 
| - | 
| -/* | 
| -** Deal with delayed interrupts/requested reschedule during interrupt | 
| -** re-enables. | 
| -*/ | 
| -void _PR_IntsOn(_PRCPU *cpu) | 
| -{ | 
| -    PRUintn missed, pri, i; | 
| -    _PRInterruptTable *it; | 
| -    PRThread *me; | 
| - | 
| -    PR_ASSERT(cpu);   /* Global threads don't have CPUs */ | 
| -    PR_ASSERT(_PR_MD_GET_INTSOFF() > 0); | 
| -	me = _PR_MD_CURRENT_THREAD(); | 
| -    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); | 
| - | 
| -    /* | 
| -    ** Process delayed interrupts. This logic is kinda scary because we | 
| -    ** need to avoid losing an interrupt (it's ok to delay an interrupt | 
| -    ** until later). | 
| -    ** | 
| -    ** There are two missed state words. _pr_ints.where indicates to the | 
| -    ** interrupt handler which state word is currently safe for | 
| -    ** modification. | 
| -    ** | 
| -    ** This code scans both interrupt state words, using the where flag | 
| -    ** to indicate to the interrupt which state word is safe for writing. | 
| -    ** If an interrupt comes in during a scan the other word will be | 
| -    ** modified. This modification will be noticed during the next | 
| -    ** iteration of the loop or during the next call to this routine. | 
| -    */ | 
| -    for (i = 0; i < 2; i++) { | 
| -        cpu->where = (1 - i); | 
| -        missed = cpu->u.missed[i]; | 
| -        if (missed != 0) { | 
| -            cpu->u.missed[i] = 0; | 
| -            for (it = _pr_interruptTable; it->name; it++) { | 
| -                if (missed & it->missed_bit) { | 
| -                    PR_LOG(_pr_sched_lm, PR_LOG_MIN, | 
| -                           ("IntsOn[0]: %s intr", it->name)); | 
| -                    (*it->handler)(); | 
| -                } | 
| -            } | 
| -        } | 
| -    } | 
| - | 
| -    if (cpu->u.missed[3] != 0) { | 
| -        _PRCPU *cpu; | 
| - | 
| -		_PR_THREAD_LOCK(me); | 
| -        me->state = _PR_RUNNABLE; | 
| -        pri = me->priority; | 
| - | 
| -        cpu = me->cpu; | 
| -		_PR_RUNQ_LOCK(cpu); | 
| -        _PR_ADD_RUNQ(me, cpu, pri); | 
| -		_PR_RUNQ_UNLOCK(cpu); | 
| -		_PR_THREAD_UNLOCK(me); | 
| -        _PR_MD_SWITCH_CONTEXT(me); | 
| -    } | 
| -} | 
| - | 
| -/* | 
| -** Unblock the first runnable waiting thread. Skip over | 
| -** threads that are trying to be suspended | 
| -** Note: Caller must hold _PR_LOCK_LOCK() | 
| -*/ | 
| -void _PR_UnblockLockWaiter(PRLock *lock) | 
| -{ | 
| -    PRThread *t = NULL; | 
| -    PRThread *me; | 
| -    PRCList *q; | 
| - | 
| -    q = lock->waitQ.next; | 
| -    PR_ASSERT(q != &lock->waitQ); | 
| -    while (q != &lock->waitQ) { | 
| -        /* Unblock first waiter */ | 
| -        t = _PR_THREAD_CONDQ_PTR(q); | 
| - | 
| -		/* | 
| -		** We are about to change the thread's state to runnable and for local | 
| -		** threads, we are going to assign a cpu to it.  So, protect thread's | 
| -		** data structure. | 
| -		*/ | 
| -        _PR_THREAD_LOCK(t); | 
| - | 
| -        if (t->flags & _PR_SUSPENDING) { | 
| -            q = q->next; | 
| -            _PR_THREAD_UNLOCK(t); | 
| -            continue; | 
| -        } | 
| - | 
| -        /* Found a runnable thread */ | 
| -	    PR_ASSERT(t->state == _PR_LOCK_WAIT); | 
| -	    PR_ASSERT(t->wait.lock == lock); | 
| -        t->wait.lock = 0; | 
| -        PR_REMOVE_LINK(&t->waitQLinks);         /* take it off lock's waitQ */ | 
| - | 
| -		/* | 
| -		** If this is a native thread, nothing else to do except to wake it | 
| -		** up by calling the machine dependent wakeup routine. | 
| -		** | 
| -		** If this is a local thread, we need to assign it a cpu and | 
| -		** put the thread on that cpu's run queue.  There are two cases to | 
| -		** take care of.  If the currently running thread is also a local | 
| -		** thread, we just assign our own cpu to that thread and put it on | 
| -		** the cpu's run queue.  If the the currently running thread is a | 
| -		** native thread, we assign the primordial cpu to it (on NT, | 
| -		** MD_WAKEUP handles the cpu assignment). | 
| -		*/ | 
| - | 
| -        if ( !_PR_IS_NATIVE_THREAD(t) ) { | 
| - | 
| -            t->state = _PR_RUNNABLE; | 
| - | 
| -            me = _PR_MD_CURRENT_THREAD(); | 
| - | 
| -            _PR_AddThreadToRunQ(me, t); | 
| -            _PR_THREAD_UNLOCK(t); | 
| -        } else { | 
| -            t->state = _PR_RUNNING; | 
| -            _PR_THREAD_UNLOCK(t); | 
| -        } | 
| -        _PR_MD_WAKEUP_WAITER(t); | 
| -        break; | 
| -    } | 
| -    return; | 
| -} | 
| - | 
| -/************************************************************************/ | 
| - | 
| - | 
| -PR_IMPLEMENT(PRLock*) PR_NewLock(void) | 
| -{ | 
| -    PRLock *lock; | 
| - | 
| -    if (!_pr_initialized) _PR_ImplicitInitialization(); | 
| - | 
| -    lock = PR_NEWZAP(PRLock); | 
| -    if (lock) { | 
| -        if (_PR_MD_NEW_LOCK(&lock->ilock) == PR_FAILURE) { | 
| -		PR_DELETE(lock); | 
| -		return(NULL); | 
| -	} | 
| -        PR_INIT_CLIST(&lock->links); | 
| -        PR_INIT_CLIST(&lock->waitQ); | 
| -    } | 
| -    return lock; | 
| -} | 
| - | 
| -/* | 
| -** Destroy the given lock "lock". There is no point in making this race | 
| -** free because if some other thread has the pointer to this lock all | 
| -** bets are off. | 
| -*/ | 
| -PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock) | 
| -{ | 
| -    PR_ASSERT(lock->owner == 0); | 
| -	_PR_MD_FREE_LOCK(&lock->ilock); | 
| -    PR_DELETE(lock); | 
| -} | 
| - | 
| -extern PRThread *suspendAllThread; | 
| -/* | 
| -** Lock the lock. | 
| -*/ | 
| -PR_IMPLEMENT(void) PR_Lock(PRLock *lock) | 
| -{ | 
| -    PRThread *me = _PR_MD_CURRENT_THREAD(); | 
| -    PRIntn is; | 
| -    PRThread *t; | 
| -    PRCList *q; | 
| - | 
| -    PR_ASSERT(me != suspendAllThread); | 
| -    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); | 
| -    PR_ASSERT(lock != NULL); | 
| -#ifdef _PR_GLOBAL_THREADS_ONLY | 
| -    PR_ASSERT(lock->owner != me); | 
| -    _PR_MD_LOCK(&lock->ilock); | 
| -    lock->owner = me; | 
| -    return; | 
| -#else  /* _PR_GLOBAL_THREADS_ONLY */ | 
| - | 
| -	if (_native_threads_only) { | 
| -		PR_ASSERT(lock->owner != me); | 
| -		_PR_MD_LOCK(&lock->ilock); | 
| -		lock->owner = me; | 
| -		return; | 
| -	} | 
| - | 
| -    if (!_PR_IS_NATIVE_THREAD(me)) | 
| -    	_PR_INTSOFF(is); | 
| - | 
| -    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); | 
| - | 
| -retry: | 
| -    _PR_LOCK_LOCK(lock); | 
| -    if (lock->owner == 0) { | 
| -        /* Just got the lock */ | 
| -        lock->owner = me; | 
| -        lock->priority = me->priority; | 
| -		/* Add the granted lock to this owning thread's lock list */ | 
| -        PR_APPEND_LINK(&lock->links, &me->lockList); | 
| -        _PR_LOCK_UNLOCK(lock); | 
| -    	if (!_PR_IS_NATIVE_THREAD(me)) | 
| -        	_PR_FAST_INTSON(is); | 
| -        return; | 
| -    } | 
| - | 
| -    /* If this thread already owns this lock, then it is a deadlock */ | 
| -    PR_ASSERT(lock->owner != me); | 
| - | 
| -    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0); | 
| - | 
| -#if 0 | 
| -    if (me->priority > lock->owner->priority) { | 
| -        /* | 
| -        ** Give the lock owner a priority boost until we get the | 
| -        ** lock. Record the priority we boosted it to. | 
| -        */ | 
| -        lock->boostPriority = me->priority; | 
| -        _PR_SetThreadPriority(lock->owner, me->priority); | 
| -    } | 
| -#endif | 
| - | 
| -    /* | 
| -    Add this thread to the asked for lock's list of waiting threads.  We | 
| -    add this thread thread in the right priority order so when the unlock | 
| -    occurs, the thread with the higher priority will get the lock. | 
| -    */ | 
| -    q = lock->waitQ.next; | 
| -    if (q == &lock->waitQ || _PR_THREAD_CONDQ_PTR(q)->priority == | 
| -      	_PR_THREAD_CONDQ_PTR(lock->waitQ.prev)->priority) { | 
| -		/* | 
| -		 * If all the threads in the lock waitQ have the same priority, | 
| -		 * then avoid scanning the list:  insert the element at the end. | 
| -		 */ | 
| -		q = &lock->waitQ; | 
| -    } else { | 
| -		/* Sort thread into lock's waitQ at appropriate point */ | 
| -		/* Now scan the list for where to insert this entry */ | 
| -		while (q != &lock->waitQ) { | 
| -			t = _PR_THREAD_CONDQ_PTR(lock->waitQ.next); | 
| -			if (me->priority > t->priority) { | 
| -				/* Found a lower priority thread to insert in front of */ | 
| -				break; | 
| -			} | 
| -			q = q->next; | 
| -		} | 
| -	} | 
| -    PR_INSERT_BEFORE(&me->waitQLinks, q); | 
| - | 
| -	/* | 
| -	Now grab the threadLock since we are about to change the state.  We have | 
| -	to do this since a PR_Suspend or PR_SetThreadPriority type call that takes | 
| -	a PRThread* as an argument could be changing the state of this thread from | 
| -	a thread running on a different cpu. | 
| -	*/ | 
| - | 
| -    _PR_THREAD_LOCK(me); | 
| -    me->state = _PR_LOCK_WAIT; | 
| -    me->wait.lock = lock; | 
| -    _PR_THREAD_UNLOCK(me); | 
| - | 
| -    _PR_LOCK_UNLOCK(lock); | 
| - | 
| -    _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT); | 
| -	goto retry; | 
| - | 
| -#endif  /* _PR_GLOBAL_THREADS_ONLY */ | 
| -} | 
| - | 
| -/* | 
| -** Unlock the lock. | 
| -*/ | 
| -PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock) | 
| -{ | 
| -    PRCList *q; | 
| -    PRThreadPriority pri, boost; | 
| -    PRIntn is; | 
| -    PRThread *me = _PR_MD_CURRENT_THREAD(); | 
| - | 
| -    PR_ASSERT(lock != NULL); | 
| -    PR_ASSERT(lock->owner == me); | 
| -    PR_ASSERT(me != suspendAllThread); | 
| -    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); | 
| -    if (lock->owner != me) { | 
| -        return PR_FAILURE; | 
| -    } | 
| - | 
| -#ifdef _PR_GLOBAL_THREADS_ONLY | 
| -    lock->owner = 0; | 
| -    _PR_MD_UNLOCK(&lock->ilock); | 
| -    return PR_SUCCESS; | 
| -#else  /* _PR_GLOBAL_THREADS_ONLY */ | 
| - | 
| -	if (_native_threads_only) { | 
| -		lock->owner = 0; | 
| -		_PR_MD_UNLOCK(&lock->ilock); | 
| -		return PR_SUCCESS; | 
| -	} | 
| - | 
| -    if (!_PR_IS_NATIVE_THREAD(me)) | 
| -    	_PR_INTSOFF(is); | 
| -    _PR_LOCK_LOCK(lock); | 
| - | 
| -	/* Remove the lock from the owning thread's lock list */ | 
| -    PR_REMOVE_LINK(&lock->links); | 
| -    pri = lock->priority; | 
| -    boost = lock->boostPriority; | 
| -    if (boost > pri) { | 
| -        /* | 
| -        ** We received a priority boost during the time we held the lock. | 
| -        ** We need to figure out what priority to move to by scanning | 
| -        ** down our list of lock's that we are still holding and using | 
| -        ** the highest boosted priority found. | 
| -        */ | 
| -        q = me->lockList.next; | 
| -        while (q != &me->lockList) { | 
| -            PRLock *ll = _PR_LOCK_PTR(q); | 
| -            if (ll->boostPriority > pri) { | 
| -                pri = ll->boostPriority; | 
| -            } | 
| -            q = q->next; | 
| -        } | 
| -        if (pri != me->priority) { | 
| -            _PR_SetThreadPriority(me, pri); | 
| -        } | 
| -    } | 
| - | 
| -    /* Unblock the first waiting thread */ | 
| -    q = lock->waitQ.next; | 
| -    if (q != &lock->waitQ) | 
| -        _PR_UnblockLockWaiter(lock); | 
| -    lock->boostPriority = PR_PRIORITY_LOW; | 
| -    lock->owner = 0; | 
| -    _PR_LOCK_UNLOCK(lock); | 
| -    if (!_PR_IS_NATIVE_THREAD(me)) | 
| -    	_PR_INTSON(is); | 
| -    return PR_SUCCESS; | 
| -#endif  /* _PR_GLOBAL_THREADS_ONLY */ | 
| -} | 
| - | 
| -/* | 
| -**  If the current thread owns |lock|, this assertion is guaranteed to | 
| -**  succeed.  Otherwise, the behavior of this function is undefined. | 
| -*/ | 
| -PR_IMPLEMENT(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock) | 
| -{ | 
| -    PRThread *me = _PR_MD_CURRENT_THREAD(); | 
| -    PR_ASSERT(lock->owner == me); | 
| -} | 
| - | 
| -/* | 
| -** Test and then lock the lock if it's not already locked by some other | 
| -** thread. Return PR_FALSE if some other thread owned the lock at the | 
| -** time of the call. | 
| -*/ | 
| -PR_IMPLEMENT(PRBool) PR_TestAndLock(PRLock *lock) | 
| -{ | 
| -    PRThread *me = _PR_MD_CURRENT_THREAD(); | 
| -    PRBool rv = PR_FALSE; | 
| -    PRIntn is; | 
| - | 
| -#ifdef _PR_GLOBAL_THREADS_ONLY | 
| -    is = _PR_MD_TEST_AND_LOCK(&lock->ilock); | 
| -    if (is == 0) { | 
| -        lock->owner = me; | 
| -        return PR_TRUE; | 
| -    } | 
| -    return PR_FALSE; | 
| -#else  /* _PR_GLOBAL_THREADS_ONLY */ | 
| - | 
| -#ifndef _PR_LOCAL_THREADS_ONLY | 
| -	if (_native_threads_only) { | 
| -		is = _PR_MD_TEST_AND_LOCK(&lock->ilock); | 
| -		if (is == 0) { | 
| -			lock->owner = me; | 
| -			return PR_TRUE; | 
| -		} | 
| -    	return PR_FALSE; | 
| -	} | 
| -#endif | 
| - | 
| -    if (!_PR_IS_NATIVE_THREAD(me)) | 
| -    	_PR_INTSOFF(is); | 
| - | 
| -    _PR_LOCK_LOCK(lock); | 
| -    if (lock->owner == 0) { | 
| -        /* Just got the lock */ | 
| -        lock->owner = me; | 
| -        lock->priority = me->priority; | 
| -		/* Add the granted lock to this owning thread's lock list */ | 
| -        PR_APPEND_LINK(&lock->links, &me->lockList); | 
| -        rv = PR_TRUE; | 
| -    } | 
| -    _PR_LOCK_UNLOCK(lock); | 
| - | 
| -    if (!_PR_IS_NATIVE_THREAD(me)) | 
| -    	_PR_INTSON(is); | 
| -    return rv; | 
| -#endif  /* _PR_GLOBAL_THREADS_ONLY */ | 
| -} | 
| - | 
| -/************************************************************************/ | 
| -/************************************************************************/ | 
| -/***********************ROUTINES FOR DCE EMULATION***********************/ | 
| -/************************************************************************/ | 
| -/************************************************************************/ | 
| -PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock) | 
| -    { return (PR_TestAndLock(lock)) ? PR_SUCCESS : PR_FAILURE; } | 
|  |