/* -*- 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 <signal.h>
#include <string.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

/* _pr_activeLock protects the following global variables */
PRLock *_pr_activeLock;
PRInt32 _pr_primordialExitCount;   /* In PR_Cleanup(), the primordial thread
                    * waits until all other user (non-system)
                    * threads have terminated before it exits.
                    * So whenever we decrement _pr_userActive,
                    * it is compared with
                    * _pr_primordialExitCount.
                    * If the primordial thread is a system
                    * thread, then _pr_primordialExitCount
                    * is 0.  If the primordial thread is
                    * itself a user thread, then
                    * _pr_primordialThread is 1.
                    */
PRCondVar *_pr_primordialExitCVar; /* When _pr_userActive is decremented to
                    * _pr_primordialExitCount, this condition
                    * variable is notified.
                    */

PRLock *_pr_deadQLock;
PRUint32 _pr_numNativeDead;
PRUint32 _pr_numUserDead;
PRCList _pr_deadNativeQ;
PRCList _pr_deadUserQ;

PRUint32 _pr_join_counter;

PRUint32 _pr_local_threads;
PRUint32 _pr_global_threads;

PRBool suspendAllOn = PR_FALSE;
PRThread *suspendAllThread = NULL;

extern PRCList _pr_active_global_threadQ;
extern PRCList _pr_active_local_threadQ;

static void _PR_DecrActiveThreadCount(PRThread *thread);
static PRThread *_PR_AttachThread(PRThreadType, PRThreadPriority, PRThreadStack *);
static void _PR_InitializeNativeStack(PRThreadStack *ts);
static void _PR_InitializeRecycledThread(PRThread *thread);
static void _PR_UserRunThread(void);

void _PR_InitThreads(PRThreadType type, PRThreadPriority priority,
                     PRUintn maxPTDs)
{
    PRThread *thread;
    PRThreadStack *stack;

    PR_ASSERT(priority == PR_PRIORITY_NORMAL);

    _pr_terminationCVLock = PR_NewLock();
    _pr_activeLock = PR_NewLock();

#ifndef HAVE_CUSTOM_USER_THREADS
    stack = PR_NEWZAP(PRThreadStack);
#ifdef HAVE_STACK_GROWING_UP
    stack->stackTop = (char*) ((((PRWord)&type) >> _pr_pageShift)
                               << _pr_pageShift);
#else
#if defined(SOLARIS) || defined (UNIXWARE) && defined (USR_SVR4_THREADS)
    stack->stackTop = (char*) &thread;
#else
    stack->stackTop = (char*) ((((PRWord)&type + _pr_pageSize - 1)
                                >> _pr_pageShift) << _pr_pageShift);
#endif
#endif
#else
    /* If stack is NULL, we're using custom user threads like NT fibers. */
    stack = PR_NEWZAP(PRThreadStack);
    if (stack) {
        stack->stackSize = 0;
        _PR_InitializeNativeStack(stack);
    }
#endif /* HAVE_CUSTOM_USER_THREADS */

    thread = _PR_AttachThread(type, priority, stack);
    if (thread) {
        _PR_MD_SET_CURRENT_THREAD(thread);

        if (type == PR_SYSTEM_THREAD) {
            thread->flags = _PR_SYSTEM;
            _pr_systemActive++;
            _pr_primordialExitCount = 0;
        } else {
            _pr_userActive++;
            _pr_primordialExitCount = 1;
        }
        thread->no_sched = 1;
        _pr_primordialExitCVar = PR_NewCondVar(_pr_activeLock);
    }

    if (!thread) {
        PR_Abort();
    }
#ifdef _PR_LOCAL_THREADS_ONLY
    thread->flags |= _PR_PRIMORDIAL;
#else
    thread->flags |= _PR_PRIMORDIAL | _PR_GLOBAL_SCOPE;
#endif

    /*
     * Needs _PR_PRIMORDIAL flag set before calling
     * _PR_MD_INIT_THREAD()
     */
    if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
        /*
         * XXX do what?
         */
    }

    if (_PR_IS_NATIVE_THREAD(thread)) {
        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_GLOBAL_THREADQ());
        _pr_global_threads++;
    } else {
        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_LOCAL_THREADQ());
        _pr_local_threads++;
    }

    _pr_recycleThreads = 0;
    _pr_deadQLock = PR_NewLock();
    _pr_numNativeDead = 0;
    _pr_numUserDead = 0;
    PR_INIT_CLIST(&_pr_deadNativeQ);
    PR_INIT_CLIST(&_pr_deadUserQ);
}

void _PR_CleanupThreads(void)
{
    if (_pr_terminationCVLock) {
        PR_DestroyLock(_pr_terminationCVLock);
        _pr_terminationCVLock = NULL;
    }
    if (_pr_activeLock) {
        PR_DestroyLock(_pr_activeLock);
        _pr_activeLock = NULL;
    }
    if (_pr_primordialExitCVar) {
        PR_DestroyCondVar(_pr_primordialExitCVar);
        _pr_primordialExitCVar = NULL;
    }
    /* TODO _pr_dead{Native,User}Q need to be deleted */
    if (_pr_deadQLock) {
        PR_DestroyLock(_pr_deadQLock);
        _pr_deadQLock = NULL;
    }
}

/*
** Initialize a stack for a native thread
*/
static void _PR_InitializeNativeStack(PRThreadStack *ts)
{
    if( ts && (ts->stackTop == 0) ) {
        ts->allocSize = ts->stackSize;

        /*
        ** Setup stackTop and stackBottom values.
        */
#ifdef HAVE_STACK_GROWING_UP
        ts->allocBase = (char*) ((((PRWord)&ts) >> _pr_pageShift)
                                 << _pr_pageShift);
        ts->stackBottom = ts->allocBase + ts->stackSize;
        ts->stackTop = ts->allocBase;
#else
        ts->allocBase = (char*) ((((PRWord)&ts + _pr_pageSize - 1)
                                  >> _pr_pageShift) << _pr_pageShift);
        ts->stackTop    = ts->allocBase;
        ts->stackBottom = ts->allocBase - ts->stackSize;
#endif
    }
}

void _PR_NotifyJoinWaiters(PRThread *thread)
{
    /*
    ** Handle joinable threads.  Change the state to waiting for join.
    ** Remove from our run Q and put it on global waiting to join Q.
    ** Notify on our "termination" condition variable so that joining
    ** thread will know about our termination.  Switch our context and
    ** come back later on to continue the cleanup.
    */
    PR_ASSERT(thread == _PR_MD_CURRENT_THREAD());
    if (thread->term != NULL) {
        PR_Lock(_pr_terminationCVLock);
        _PR_THREAD_LOCK(thread);
        thread->state = _PR_JOIN_WAIT;
        if ( !_PR_IS_NATIVE_THREAD(thread) ) {
            _PR_MISCQ_LOCK(thread->cpu);
            _PR_ADD_JOINQ(thread, thread->cpu);
            _PR_MISCQ_UNLOCK(thread->cpu);
        }
        _PR_THREAD_UNLOCK(thread);
        PR_NotifyCondVar(thread->term);
        PR_Unlock(_pr_terminationCVLock);
        _PR_MD_WAIT(thread, PR_INTERVAL_NO_TIMEOUT);
        PR_ASSERT(thread->state != _PR_JOIN_WAIT);
    }

}

/*
 * Zero some of the data members of a recycled thread.
 *
 * Note that we can do this either when a dead thread is added to
 * the dead thread queue or when it is reused.  Here, we are doing
 * this lazily, when the thread is reused in _PR_CreateThread().
 */
static void _PR_InitializeRecycledThread(PRThread *thread)
{
    /*
     * Assert that the following data members are already zeroed
     * by _PR_CleanupThread().
     */
#ifdef DEBUG
    if (thread->privateData) {
        unsigned int i;
        for (i = 0; i < thread->tpdLength; i++) {
            PR_ASSERT(thread->privateData[i] == NULL);
        }
    }
#endif
    PR_ASSERT(thread->dumpArg == 0 && thread->dump == 0);
    PR_ASSERT(thread->errorString == 0 && thread->errorStringSize == 0);
    PR_ASSERT(thread->errorStringLength == 0);
    PR_ASSERT(thread->name == 0);

    /* Reset data members in thread structure */
    thread->errorCode = thread->osErrorCode = 0;
    thread->io_pending = thread->io_suspended = PR_FALSE;
    thread->environment = 0;
    PR_INIT_CLIST(&thread->lockList);
}

PRStatus _PR_RecycleThread(PRThread *thread)
{
    if ( _PR_IS_NATIVE_THREAD(thread) &&
         _PR_NUM_DEADNATIVE < _pr_recycleThreads) {
        _PR_DEADQ_LOCK;
        PR_APPEND_LINK(&thread->links, &_PR_DEADNATIVEQ);
        _PR_INC_DEADNATIVE;
        _PR_DEADQ_UNLOCK;
        return (PR_SUCCESS);
    } else if ( !_PR_IS_NATIVE_THREAD(thread) &&
                _PR_NUM_DEADUSER < _pr_recycleThreads) {
        _PR_DEADQ_LOCK;
        PR_APPEND_LINK(&thread->links, &_PR_DEADUSERQ);
        _PR_INC_DEADUSER;
        _PR_DEADQ_UNLOCK;
        return (PR_SUCCESS);
    }
    return (PR_FAILURE);
}

/*
 * Decrement the active thread count, either _pr_systemActive or
 * _pr_userActive, depending on whether the thread is a system thread
 * or a user thread.  If all the user threads, except possibly
 * the primordial thread, have terminated, we notify the primordial
 * thread of this condition.
 *
 * Since this function will lock _pr_activeLock, do not call this
 * function while holding the _pr_activeLock lock, as this will result
 * in a deadlock.
 */

static void
_PR_DecrActiveThreadCount(PRThread *thread)
{
    PR_Lock(_pr_activeLock);
    if (thread->flags & _PR_SYSTEM) {
        _pr_systemActive--;
    } else {
        _pr_userActive--;
        if (_pr_userActive == _pr_primordialExitCount) {
            PR_NotifyCondVar(_pr_primordialExitCVar);
        }
    }
    PR_Unlock(_pr_activeLock);
}

/*
** Detach thread structure
*/
static void
_PR_DestroyThread(PRThread *thread)
{
    _PR_MD_FREE_LOCK(&thread->threadLock);
    PR_DELETE(thread);
}

void
_PR_NativeDestroyThread(PRThread *thread)
{
    if(thread->term) {
        PR_DestroyCondVar(thread->term);
        thread->term = 0;
    }
    if (NULL != thread->privateData) {
        PR_ASSERT(0 != thread->tpdLength);
        PR_DELETE(thread->privateData);
        thread->tpdLength = 0;
    }
    PR_DELETE(thread->stack);
    _PR_DestroyThread(thread);
}

void
_PR_UserDestroyThread(PRThread *thread)
{
    if(thread->term) {
        PR_DestroyCondVar(thread->term);
        thread->term = 0;
    }
    if (NULL != thread->privateData) {
        PR_ASSERT(0 != thread->tpdLength);
        PR_DELETE(thread->privateData);
        thread->tpdLength = 0;
    }
    _PR_MD_FREE_LOCK(&thread->threadLock);
    if (thread->threadAllocatedOnStack == 1) {
        _PR_MD_CLEAN_THREAD(thread);
        /*
         *  Because the no_sched field is set, this thread/stack will
         *  will not be re-used until the flag is cleared by the thread
         *  we will context switch to.
         */
        _PR_FreeStack(thread->stack);
    } else {
#ifdef WINNT
        _PR_MD_CLEAN_THREAD(thread);
#else
        /*
         * This assertion does not apply to NT.  On NT, every fiber
         * has its threadAllocatedOnStack equal to 0.  Elsewhere,
         * only the primordial thread has its threadAllocatedOnStack
         * equal to 0.
         */
        PR_ASSERT(thread->flags & _PR_PRIMORDIAL);
#endif
    }
}


/*
** Run a thread's start function. When the start function returns the
** thread is done executing and no longer needs the CPU. If there are no
** more user threads running then we can exit the program.
*/
void _PR_NativeRunThread(void *arg)
{
    PRThread *thread = (PRThread *)arg;

    _PR_MD_SET_CURRENT_THREAD(thread);

    _PR_MD_SET_CURRENT_CPU(NULL);

    /* Set up the thread stack information */
    _PR_InitializeNativeStack(thread->stack);

    /* Set up the thread md information */
    if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
        /*
         * thread failed to initialize itself, possibly due to
         * failure to allocate per-thread resources
         */
        return;
    }

    while(1) {
        thread->state = _PR_RUNNING;

        /*
         * Add to list of active threads
         */
        PR_Lock(_pr_activeLock);
        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_GLOBAL_THREADQ());
        _pr_global_threads++;
        PR_Unlock(_pr_activeLock);

        (*thread->startFunc)(thread->arg);

        /*
         * The following two assertions are meant for NT asynch io.
         *
         * The thread should have no asynch io in progress when it
         * exits, otherwise the overlapped buffer, which is part of
         * the thread structure, would become invalid.
         */
        PR_ASSERT(thread->io_pending == PR_FALSE);
        /*
         * This assertion enforces the programming guideline that
         * if an io function times out or is interrupted, the thread
         * should close the fd to force the asynch io to abort
         * before it exits.  Right now, closing the fd is the only
         * way to clear the io_suspended flag.
         */
        PR_ASSERT(thread->io_suspended == PR_FALSE);

        /*
         * remove thread from list of active threads
         */
        PR_Lock(_pr_activeLock);
        PR_REMOVE_LINK(&thread->active);
        _pr_global_threads--;
        PR_Unlock(_pr_activeLock);

        PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("thread exiting"));

        /* All done, time to go away */
        _PR_CleanupThread(thread);

        _PR_NotifyJoinWaiters(thread);

        _PR_DecrActiveThreadCount(thread);

        thread->state = _PR_DEAD_STATE;

        if (!_pr_recycleThreads || (_PR_RecycleThread(thread) ==
                                    PR_FAILURE)) {
            /*
             * thread not recycled
             * platform-specific thread exit processing
             *        - for stuff like releasing native-thread resources, etc.
             */
            _PR_MD_EXIT_THREAD(thread);
            /*
             * Free memory allocated for the thread
             */
            _PR_NativeDestroyThread(thread);
            /*
             * thread gone, cannot de-reference thread now
             */
            return;
        }

        /* Now wait for someone to activate us again... */
        _PR_MD_WAIT(thread, PR_INTERVAL_NO_TIMEOUT);
    }
}

static void _PR_UserRunThread(void)
{
    PRThread *thread = _PR_MD_CURRENT_THREAD();
    PRIntn is;

    if (_MD_LAST_THREAD()) {
        _MD_LAST_THREAD()->no_sched = 0;
    }

#ifdef HAVE_CUSTOM_USER_THREADS
    if (thread->stack == NULL) {
        thread->stack = PR_NEWZAP(PRThreadStack);
        _PR_InitializeNativeStack(thread->stack);
    }
#endif /* HAVE_CUSTOM_USER_THREADS */

    while(1) {
        /* Run thread main */
        if ( !_PR_IS_NATIVE_THREAD(thread)) {
            _PR_MD_SET_INTSOFF(0);
        }

        /*
         * Add to list of active threads
         */
        if (!(thread->flags & _PR_IDLE_THREAD)) {
            PR_Lock(_pr_activeLock);
            PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_LOCAL_THREADQ());
            _pr_local_threads++;
            PR_Unlock(_pr_activeLock);
        }

        (*thread->startFunc)(thread->arg);

        /*
         * The following two assertions are meant for NT asynch io.
         *
         * The thread should have no asynch io in progress when it
         * exits, otherwise the overlapped buffer, which is part of
         * the thread structure, would become invalid.
         */
        PR_ASSERT(thread->io_pending == PR_FALSE);
        /*
         * This assertion enforces the programming guideline that
         * if an io function times out or is interrupted, the thread
         * should close the fd to force the asynch io to abort
         * before it exits.  Right now, closing the fd is the only
         * way to clear the io_suspended flag.
         */
        PR_ASSERT(thread->io_suspended == PR_FALSE);

        PR_Lock(_pr_activeLock);
        /*
         * remove thread from list of active threads
         */
        if (!(thread->flags & _PR_IDLE_THREAD)) {
            PR_REMOVE_LINK(&thread->active);
            _pr_local_threads--;
        }
        PR_Unlock(_pr_activeLock);
        PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("thread exiting"));

        /* All done, time to go away */
        _PR_CleanupThread(thread);

        _PR_INTSOFF(is);

        _PR_NotifyJoinWaiters(thread);

        _PR_DecrActiveThreadCount(thread);

        thread->state = _PR_DEAD_STATE;

        if (!_pr_recycleThreads || (_PR_RecycleThread(thread) ==
                                    PR_FAILURE)) {
            /*
            ** Destroy the thread resources
            */
            _PR_UserDestroyThread(thread);
        }

        /*
        ** Find another user thread to run. This cpu has finished the
        ** previous threads main and is now ready to run another thread.
        */
        {
            PRInt32 is;
            _PR_INTSOFF(is);
            _PR_MD_SWITCH_CONTEXT(thread);
        }

        /* Will land here when we get scheduled again if we are recycling... */
    }
}

void _PR_SetThreadPriority(PRThread *thread, PRThreadPriority newPri)
{
    PRThread *me = _PR_MD_CURRENT_THREAD();
    PRIntn is;

    if ( _PR_IS_NATIVE_THREAD(thread) ) {
        _PR_MD_SET_PRIORITY(&(thread->md), newPri);
        return;
    }

    if (!_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSOFF(is);
    }
    _PR_THREAD_LOCK(thread);
    if (newPri != thread->priority) {
        _PRCPU *cpu = thread->cpu;

        switch (thread->state) {
            case _PR_RUNNING:
                /* Change my priority */

                _PR_RUNQ_LOCK(cpu);
                thread->priority = newPri;
                if (_PR_RUNQREADYMASK(cpu) >> (newPri + 1)) {
                    if (!_PR_IS_NATIVE_THREAD(me)) {
                        _PR_SET_RESCHED_FLAG();
                    }
                }
                _PR_RUNQ_UNLOCK(cpu);
                break;

            case _PR_RUNNABLE:

                _PR_RUNQ_LOCK(cpu);
                /* Move to different runQ */
                _PR_DEL_RUNQ(thread);
                thread->priority = newPri;
                PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
                _PR_ADD_RUNQ(thread, cpu, newPri);
                _PR_RUNQ_UNLOCK(cpu);

                if (newPri > me->priority) {
                    if (!_PR_IS_NATIVE_THREAD(me)) {
                        _PR_SET_RESCHED_FLAG();
                    }
                }

                break;

            case _PR_LOCK_WAIT:
            case _PR_COND_WAIT:
            case _PR_IO_WAIT:
            case _PR_SUSPENDED:

                thread->priority = newPri;
                break;
        }
    }
    _PR_THREAD_UNLOCK(thread);
    if (!_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSON(is);
    }
}

/*
** Suspend the named thread and copy its gc registers into regBuf
*/
static void _PR_Suspend(PRThread *thread)
{
    PRIntn is;
    PRThread *me = _PR_MD_CURRENT_THREAD();

    PR_ASSERT(thread != me);
    PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread) || (!thread->cpu));

    if (!_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSOFF(is);
    }
    _PR_THREAD_LOCK(thread);
    switch (thread->state) {
        case _PR_RUNNABLE:
            if (!_PR_IS_NATIVE_THREAD(thread)) {
                _PR_RUNQ_LOCK(thread->cpu);
                _PR_DEL_RUNQ(thread);
                _PR_RUNQ_UNLOCK(thread->cpu);

                _PR_MISCQ_LOCK(thread->cpu);
                _PR_ADD_SUSPENDQ(thread, thread->cpu);
                _PR_MISCQ_UNLOCK(thread->cpu);
            } else {
                /*
                 * Only LOCAL threads are suspended by _PR_Suspend
                 */
                PR_ASSERT(0);
            }
            thread->state = _PR_SUSPENDED;
            break;

        case _PR_RUNNING:
            /*
             * The thread being suspended should be a LOCAL thread with
             * _pr_numCPUs == 1. Hence, the thread cannot be in RUNNING state
             */
            PR_ASSERT(0);
            break;

        case _PR_LOCK_WAIT:
        case _PR_IO_WAIT:
        case _PR_COND_WAIT:
            if (_PR_IS_NATIVE_THREAD(thread)) {
                _PR_MD_SUSPEND_THREAD(thread);
            }
            thread->flags |= _PR_SUSPENDING;
            break;

        default:
            PR_Abort();
    }
    _PR_THREAD_UNLOCK(thread);
    if (!_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSON(is);
    }
}

static void _PR_Resume(PRThread *thread)
{
    PRThreadPriority pri;
    PRIntn is;
    PRThread *me = _PR_MD_CURRENT_THREAD();

    if (!_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSOFF(is);
    }
    _PR_THREAD_LOCK(thread);
    switch (thread->state) {
        case _PR_SUSPENDED:
            thread->state = _PR_RUNNABLE;
            thread->flags &= ~_PR_SUSPENDING;
            if (!_PR_IS_NATIVE_THREAD(thread)) {
                _PR_MISCQ_LOCK(thread->cpu);
                _PR_DEL_SUSPENDQ(thread);
                _PR_MISCQ_UNLOCK(thread->cpu);

                pri = thread->priority;

                _PR_RUNQ_LOCK(thread->cpu);
                _PR_ADD_RUNQ(thread, thread->cpu, pri);
                _PR_RUNQ_UNLOCK(thread->cpu);

                if (pri > _PR_MD_CURRENT_THREAD()->priority) {
                    if (!_PR_IS_NATIVE_THREAD(me)) {
                        _PR_SET_RESCHED_FLAG();
                    }
                }
            } else {
                PR_ASSERT(0);
            }
            break;

        case _PR_IO_WAIT:
        case _PR_COND_WAIT:
            thread->flags &= ~_PR_SUSPENDING;
            /*      PR_ASSERT(thread->wait.monitor->stickyCount == 0); */
            break;

        case _PR_LOCK_WAIT:
        {
            PRLock *wLock = thread->wait.lock;

            thread->flags &= ~_PR_SUSPENDING;

            _PR_LOCK_LOCK(wLock);
            if (thread->wait.lock->owner == 0) {
                _PR_UnblockLockWaiter(thread->wait.lock);
            }
            _PR_LOCK_UNLOCK(wLock);
            break;
        }
        case _PR_RUNNABLE:
            break;
        case _PR_RUNNING:
            /*
             * The thread being suspended should be a LOCAL thread with
             * _pr_numCPUs == 1. Hence, the thread cannot be in RUNNING state
             */
            PR_ASSERT(0);
            break;

        default:
            /*
             * thread should have been in one of the above-listed blocked states
             * (_PR_JOIN_WAIT, _PR_IO_WAIT, _PR_UNBORN, _PR_DEAD_STATE)
             */
            PR_Abort();
    }
    _PR_THREAD_UNLOCK(thread);
    if (!_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSON(is);
    }

}

#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
static PRThread *get_thread(_PRCPU *cpu, PRBool *wakeup_cpus)
{
    PRThread *thread;
    PRIntn pri;
    PRUint32 r;
    PRCList *qp;
    PRIntn priMin, priMax;

    _PR_RUNQ_LOCK(cpu);
    r = _PR_RUNQREADYMASK(cpu);
    if (r==0) {
        priMin = priMax = PR_PRIORITY_FIRST;
    } else if (r == (1<<PR_PRIORITY_NORMAL) ) {
        priMin = priMax = PR_PRIORITY_NORMAL;
    } else {
        priMin = PR_PRIORITY_FIRST;
        priMax = PR_PRIORITY_LAST;
    }
    thread = NULL;
    for (pri = priMax; pri >= priMin ; pri-- ) {
        if (r & (1 << pri)) {
            for (qp = _PR_RUNQ(cpu)[pri].next;
                 qp != &_PR_RUNQ(cpu)[pri];
                 qp = qp->next) {
                thread = _PR_THREAD_PTR(qp);
                /*
                * skip non-schedulable threads
                */
                PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
                if (thread->no_sched) {
                    thread = NULL;
                    /*
                     * Need to wakeup cpus to avoid missing a
                     * runnable thread
                     * Waking up all CPU's need happen only once.
                     */

                    *wakeup_cpus = PR_TRUE;
                    continue;
                } else if (thread->flags & _PR_BOUND_THREAD) {
                    /*
                     * Thread bound to cpu 0
                     */

                    thread = NULL;
                    continue;
                } else if (thread->io_pending == PR_TRUE) {
                    /*
                     * A thread that is blocked for I/O needs to run
                     * on the same cpu on which it was blocked. This is because
                     * the cpu's ioq is accessed without lock protection and scheduling
                     * the thread on a different cpu would preclude this optimization.
                     */
                    thread = NULL;
                    continue;
                } else {
                    /* Pull thread off of its run queue */
                    _PR_DEL_RUNQ(thread);
                    _PR_RUNQ_UNLOCK(cpu);
                    return(thread);
                }
            }
        }
        thread = NULL;
    }
    _PR_RUNQ_UNLOCK(cpu);
    return(thread);
}
#endif /* !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) */

/*
** Schedule this native thread by finding the highest priority nspr
** thread that is ready to run.
**
** Note- everyone really needs to call _PR_MD_SWITCH_CONTEXT (which calls
**       PR_Schedule() rather than calling PR_Schedule.  Otherwise if there
**       is initialization required for switching from SWITCH_CONTEXT,
**       it will not get done!
*/
void _PR_Schedule(void)
{
    PRThread *thread, *me = _PR_MD_CURRENT_THREAD();
    _PRCPU *cpu = _PR_MD_CURRENT_CPU();
    PRIntn pri;
    PRUint32 r;
    PRCList *qp;
    PRIntn priMin, priMax;
#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
    PRBool wakeup_cpus;
#endif

    /* Interrupts must be disabled */
    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);

    /* Since we are rescheduling, we no longer want to */
    _PR_CLEAR_RESCHED_FLAG();

    /*
    ** Find highest priority thread to run. Bigger priority numbers are
    ** higher priority threads
    */
    _PR_RUNQ_LOCK(cpu);
    /*
     *  if we are in SuspendAll mode, can schedule only the thread
     *    that called PR_SuspendAll
     *
     *  The thread may be ready to run now, after completing an I/O
     *  operation, for example
     */
    if ((thread = suspendAllThread) != 0) {
        if ((!(thread->no_sched)) && (thread->state == _PR_RUNNABLE)) {
            /* Pull thread off of its run queue */
            _PR_DEL_RUNQ(thread);
            _PR_RUNQ_UNLOCK(cpu);
            goto found_thread;
        } else {
            thread = NULL;
            _PR_RUNQ_UNLOCK(cpu);
            goto idle_thread;
        }
    }
    r = _PR_RUNQREADYMASK(cpu);
    if (r==0) {
        priMin = priMax = PR_PRIORITY_FIRST;
    } else if (r == (1<<PR_PRIORITY_NORMAL) ) {
        priMin = priMax = PR_PRIORITY_NORMAL;
    } else {
        priMin = PR_PRIORITY_FIRST;
        priMax = PR_PRIORITY_LAST;
    }
    thread = NULL;
    for (pri = priMax; pri >= priMin ; pri-- ) {
        if (r & (1 << pri)) {
            for (qp = _PR_RUNQ(cpu)[pri].next;
                 qp != &_PR_RUNQ(cpu)[pri];
                 qp = qp->next) {
                thread = _PR_THREAD_PTR(qp);
                /*
                * skip non-schedulable threads
                */
                PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
                if ((thread->no_sched) && (me != thread)) {
                    thread = NULL;
                    continue;
                } else {
                    /* Pull thread off of its run queue */
                    _PR_DEL_RUNQ(thread);
                    _PR_RUNQ_UNLOCK(cpu);
                    goto found_thread;
                }
            }
        }
        thread = NULL;
    }
    _PR_RUNQ_UNLOCK(cpu);

#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)

    wakeup_cpus = PR_FALSE;
    _PR_CPU_LIST_LOCK();
    for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
        if (cpu != _PR_CPU_PTR(qp)) {
            if ((thread = get_thread(_PR_CPU_PTR(qp), &wakeup_cpus))
                != NULL) {
                thread->cpu = cpu;
                _PR_CPU_LIST_UNLOCK();
                if (wakeup_cpus == PR_TRUE) {
                    _PR_MD_WAKEUP_CPUS();
                }
                goto found_thread;
            }
        }
    }
    _PR_CPU_LIST_UNLOCK();
    if (wakeup_cpus == PR_TRUE) {
        _PR_MD_WAKEUP_CPUS();
    }

#endif        /* _PR_LOCAL_THREADS_ONLY */

idle_thread:
    /*
     ** There are no threads to run. Switch to the idle thread
     */
    PR_LOG(_pr_sched_lm, PR_LOG_MAX, ("pausing"));
    thread = _PR_MD_CURRENT_CPU()->idle_thread;

found_thread:
    PR_ASSERT((me == thread) || ((thread->state == _PR_RUNNABLE) &&
                                 (!(thread->no_sched))));

    /* Resume the thread */
    PR_LOG(_pr_sched_lm, PR_LOG_MAX,
           ("switching to %d[%p]", thread->id, thread));
    PR_ASSERT(thread->state != _PR_RUNNING);
    thread->state = _PR_RUNNING;

    /* If we are on the runq, it just means that we went to sleep on some
     * resource, and by the time we got here another real native thread had
     * already given us the resource and put us back on the runqueue
     */
    PR_ASSERT(thread->cpu == _PR_MD_CURRENT_CPU());
    if (thread != me) {
        _PR_MD_RESTORE_CONTEXT(thread);
    }
#if 0
    /* XXXMB; with setjmp/longjmp it is impossible to land here, but
     * it is not with fibers... Is this a bad thing?  I believe it is
     * still safe.
     */
    PR_NOT_REACHED("impossible return from schedule");
#endif
}

/*
** Attaches a thread.
** Does not set the _PR_MD_CURRENT_THREAD.
** Does not specify the scope of the thread.
*/
static PRThread *
_PR_AttachThread(PRThreadType type, PRThreadPriority priority,
                 PRThreadStack *stack)
{
    PRThread *thread;
    char *mem;

    if (priority > PR_PRIORITY_LAST) {
        priority = PR_PRIORITY_LAST;
    } else if (priority < PR_PRIORITY_FIRST) {
        priority = PR_PRIORITY_FIRST;
    }

    mem = (char*) PR_CALLOC(sizeof(PRThread));
    if (mem) {
        thread = (PRThread*) mem;
        thread->priority = priority;
        thread->stack = stack;
        thread->state = _PR_RUNNING;
        PR_INIT_CLIST(&thread->lockList);
        if (_PR_MD_NEW_LOCK(&thread->threadLock) == PR_FAILURE) {
            PR_DELETE(thread);
            return 0;
        }

        return thread;
    }
    return 0;
}



PR_IMPLEMENT(PRThread*)
_PR_NativeCreateThread(PRThreadType type,
                       void (*start)(void *arg),
                       void *arg,
                       PRThreadPriority priority,
                       PRThreadScope scope,
                       PRThreadState state,
                       PRUint32 stackSize,
                       PRUint32 flags)
{
    PRThread *thread;

    thread = _PR_AttachThread(type, priority, NULL);

    if (thread) {
        PR_Lock(_pr_activeLock);
        thread->flags = (flags | _PR_GLOBAL_SCOPE);
        thread->id = ++_pr_utid;
        if (type == PR_SYSTEM_THREAD) {
            thread->flags |= _PR_SYSTEM;
            _pr_systemActive++;
        } else {
            _pr_userActive++;
        }
        PR_Unlock(_pr_activeLock);

        thread->stack = PR_NEWZAP(PRThreadStack);
        if (!thread->stack) {
            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
            goto done;
        }
        thread->stack->stackSize = stackSize?stackSize:_MD_DEFAULT_STACK_SIZE;
        thread->stack->thr = thread;
        thread->startFunc = start;
        thread->arg = arg;

        /*
          Set thread flags related to scope and joinable state. If joinable
          thread, allocate a "termination" conidition variable.
         */
        if (state == PR_JOINABLE_THREAD) {
            thread->term = PR_NewCondVar(_pr_terminationCVLock);
            if (thread->term == NULL) {
                PR_DELETE(thread->stack);
                goto done;
            }
        }

        thread->state = _PR_RUNNING;
        if (_PR_MD_CREATE_THREAD(thread, _PR_NativeRunThread, priority,
                                 scope,state,stackSize) == PR_SUCCESS) {
            return thread;
        }
        if (thread->term) {
            PR_DestroyCondVar(thread->term);
            thread->term = NULL;
        }
        PR_DELETE(thread->stack);
    }

done:
    if (thread) {
        _PR_DecrActiveThreadCount(thread);
        _PR_DestroyThread(thread);
    }
    return NULL;
}

/************************************************************************/

PR_IMPLEMENT(PRThread*) _PR_CreateThread(PRThreadType type,
        void (*start)(void *arg),
        void *arg,
        PRThreadPriority priority,
        PRThreadScope scope,
        PRThreadState state,
        PRUint32 stackSize,
        PRUint32 flags)
{
    PRThread *me;
    PRThread *thread = NULL;
    PRThreadStack *stack;
    char *top;
    PRIntn is;
    PRIntn native = 0;
    PRIntn useRecycled = 0;
    PRBool status;

    /*
    First, pin down the priority.  Not all compilers catch passing out of
    range enum here.  If we let bad values thru, priority queues won't work.
    */
    if (priority > PR_PRIORITY_LAST) {
        priority = PR_PRIORITY_LAST;
    } else if (priority < PR_PRIORITY_FIRST) {
        priority = PR_PRIORITY_FIRST;
    }

    if (!_pr_initialized) {
        _PR_ImplicitInitialization();
    }

    if (! (flags & _PR_IDLE_THREAD)) {
        me = _PR_MD_CURRENT_THREAD();
    }

#if    defined(_PR_GLOBAL_THREADS_ONLY)
    /*
     * can create global threads only
     */
    if (scope == PR_LOCAL_THREAD) {
        scope = PR_GLOBAL_THREAD;
    }
#endif

    if (_native_threads_only) {
        scope = PR_GLOBAL_THREAD;
    }

    native = (((scope == PR_GLOBAL_THREAD)|| (scope == PR_GLOBAL_BOUND_THREAD))
              && _PR_IS_NATIVE_THREAD_SUPPORTED());

    _PR_ADJUST_STACKSIZE(stackSize);

    if (native) {
        /*
         * clear the IDLE_THREAD flag which applies to LOCAL
         * threads only
         */
        flags &= ~_PR_IDLE_THREAD;
        flags |= _PR_GLOBAL_SCOPE;
        if (_PR_NUM_DEADNATIVE > 0) {
            _PR_DEADQ_LOCK;

            if (_PR_NUM_DEADNATIVE == 0) { /* Thread safe check */
                _PR_DEADQ_UNLOCK;
            } else {
                thread = _PR_THREAD_PTR(_PR_DEADNATIVEQ.next);
                PR_REMOVE_LINK(&thread->links);
                _PR_DEC_DEADNATIVE;
                _PR_DEADQ_UNLOCK;

                _PR_InitializeRecycledThread(thread);
                thread->startFunc = start;
                thread->arg = arg;
                thread->flags = (flags | _PR_GLOBAL_SCOPE);
                if (type == PR_SYSTEM_THREAD)
                {
                    thread->flags |= _PR_SYSTEM;
                    PR_ATOMIC_INCREMENT(&_pr_systemActive);
                }
                else {
                    PR_ATOMIC_INCREMENT(&_pr_userActive);
                }

                if (state == PR_JOINABLE_THREAD) {
                    if (!thread->term) {
                        thread->term = PR_NewCondVar(_pr_terminationCVLock);
                    }
                }
                else {
                    if(thread->term) {
                        PR_DestroyCondVar(thread->term);
                        thread->term = 0;
                    }
                }

                thread->priority = priority;
                _PR_MD_SET_PRIORITY(&(thread->md), priority);
                /* XXX what about stackSize? */
                thread->state = _PR_RUNNING;
                _PR_MD_WAKEUP_WAITER(thread);
                return thread;
            }
        }
        thread = _PR_NativeCreateThread(type, start, arg, priority,
                                        scope, state, stackSize, flags);
    } else {
        if (_PR_NUM_DEADUSER > 0) {
            _PR_DEADQ_LOCK;

            if (_PR_NUM_DEADUSER == 0) {  /* thread safe check */
                _PR_DEADQ_UNLOCK;
            } else {
                PRCList *ptr;

                /* Go down list checking for a recycled thread with a
                 * large enough stack.  XXXMB - this has a bad degenerate case.
                 */
                ptr = _PR_DEADUSERQ.next;
                while( ptr != &_PR_DEADUSERQ ) {
                    thread = _PR_THREAD_PTR(ptr);
                    if ((thread->stack->stackSize >= stackSize) &&
                        (!thread->no_sched)) {
                        PR_REMOVE_LINK(&thread->links);
                        _PR_DEC_DEADUSER;
                        break;
                    } else {
                        ptr = ptr->next;
                        thread = NULL;
                    }
                }

                _PR_DEADQ_UNLOCK;

                if (thread) {
                    _PR_InitializeRecycledThread(thread);
                    thread->startFunc = start;
                    thread->arg = arg;
                    thread->priority = priority;
                    if (state == PR_JOINABLE_THREAD) {
                        if (!thread->term) {
                            thread->term = PR_NewCondVar(_pr_terminationCVLock);
                        }
                    } else {
                        if(thread->term) {
                            PR_DestroyCondVar(thread->term);
                            thread->term = 0;
                        }
                    }
                    useRecycled++;
                }
            }
        }
        if (thread == NULL) {
#ifndef HAVE_CUSTOM_USER_THREADS
            stack = _PR_NewStack(stackSize);
            if (!stack) {
                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
                return NULL;
            }

            /* Allocate thread object and per-thread data off the top of the stack*/
            top = stack->stackTop;
#ifdef HAVE_STACK_GROWING_UP
            thread = (PRThread*) top;
            top = top + sizeof(PRThread);
            /*
             * Make stack 64-byte aligned
             */
            if ((PRUptrdiff)top & 0x3f) {
                top = (char*)(((PRUptrdiff)top + 0x40) & ~0x3f);
            }
#else
            top = top - sizeof(PRThread);
            thread = (PRThread*) top;
            /*
             * Make stack 64-byte aligned
             */
            if ((PRUptrdiff)top & 0x3f) {
                top = (char*)((PRUptrdiff)top & ~0x3f);
            }
#endif
            stack->thr = thread;
            memset(thread, 0, sizeof(PRThread));
            thread->threadAllocatedOnStack = 1;
#else
            thread = _PR_MD_CREATE_USER_THREAD(stackSize, start, arg);
            if (!thread) {
                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
                return NULL;
            }
            thread->threadAllocatedOnStack = 0;
            stack = NULL;
            top = NULL;
#endif

            /* Initialize thread */
            thread->tpdLength = 0;
            thread->privateData = NULL;
            thread->stack = stack;
            thread->priority = priority;
            thread->startFunc = start;
            thread->arg = arg;
            PR_INIT_CLIST(&thread->lockList);

            if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
                if (thread->threadAllocatedOnStack == 1) {
                    _PR_FreeStack(thread->stack);
                }
                else {
                    PR_DELETE(thread);
                }
                PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
                return NULL;
            }

            if (_PR_MD_NEW_LOCK(&thread->threadLock) == PR_FAILURE) {
                if (thread->threadAllocatedOnStack == 1) {
                    _PR_FreeStack(thread->stack);
                }
                else {
                    PR_DELETE(thread->privateData);
                    PR_DELETE(thread);
                }
                PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
                return NULL;
            }

            _PR_MD_INIT_CONTEXT(thread, top, _PR_UserRunThread, &status);

            if (status == PR_FALSE) {
                _PR_MD_FREE_LOCK(&thread->threadLock);
                if (thread->threadAllocatedOnStack == 1) {
                    _PR_FreeStack(thread->stack);
                }
                else {
                    PR_DELETE(thread->privateData);
                    PR_DELETE(thread);
                }
                return NULL;
            }

            /*
              Set thread flags related to scope and joinable state. If joinable
              thread, allocate a "termination" condition variable.
            */
            if (state == PR_JOINABLE_THREAD) {
                thread->term = PR_NewCondVar(_pr_terminationCVLock);
                if (thread->term == NULL) {
                    _PR_MD_FREE_LOCK(&thread->threadLock);
                    if (thread->threadAllocatedOnStack == 1) {
                        _PR_FreeStack(thread->stack);
                    }
                    else {
                        PR_DELETE(thread->privateData);
                        PR_DELETE(thread);
                    }
                    return NULL;
                }
            }

        }

        /* Update thread type counter */
        PR_Lock(_pr_activeLock);
        thread->flags = flags;
        thread->id = ++_pr_utid;
        if (type == PR_SYSTEM_THREAD) {
            thread->flags |= _PR_SYSTEM;
            _pr_systemActive++;
        } else {
            _pr_userActive++;
        }

        /* Make thread runnable */
        thread->state = _PR_RUNNABLE;
        /*
         * Add to list of active threads
         */
        PR_Unlock(_pr_activeLock);

        if ((! (thread->flags & _PR_IDLE_THREAD)) && _PR_IS_NATIVE_THREAD(me) ) {
            thread->cpu = _PR_GetPrimordialCPU();
        }
        else {
            thread->cpu = _PR_MD_CURRENT_CPU();
        }

        PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread));

        if ((! (thread->flags & _PR_IDLE_THREAD)) && !_PR_IS_NATIVE_THREAD(me)) {
            _PR_INTSOFF(is);
            _PR_RUNQ_LOCK(thread->cpu);
            _PR_ADD_RUNQ(thread, thread->cpu, priority);
            _PR_RUNQ_UNLOCK(thread->cpu);
        }

        if (thread->flags & _PR_IDLE_THREAD) {
            /*
            ** If the creating thread is a kernel thread, we need to
            ** awaken the user thread idle thread somehow; potentially
            ** it could be sleeping in its idle loop, and we need to poke
            ** it.  To do so, wake the idle thread...
            */
            _PR_MD_WAKEUP_WAITER(NULL);
        } else if (_PR_IS_NATIVE_THREAD(me)) {
            _PR_MD_WAKEUP_WAITER(thread);
        }
        if ((! (thread->flags & _PR_IDLE_THREAD)) && !_PR_IS_NATIVE_THREAD(me) ) {
            _PR_INTSON(is);
        }
    }

    return thread;
}

PR_IMPLEMENT(PRThread*) PR_CreateThread(PRThreadType type,
                                        void (*start)(void *arg),
                                        void *arg,
                                        PRThreadPriority priority,
                                        PRThreadScope scope,
                                        PRThreadState state,
                                        PRUint32 stackSize)
{
    return _PR_CreateThread(type, start, arg, priority, scope, state,
                            stackSize, 0);
}

/*
** Associate a thread object with an existing native thread.
**     "type" is the type of thread object to attach
**     "priority" is the priority to assign to the thread
**     "stack" defines the shape of the threads stack
**
** This can return NULL if some kind of error occurs, or if memory is
** tight.
**
** This call is not normally needed unless you create your own native
** thread. PR_Init does this automatically for the primordial thread.
*/
PRThread* _PRI_AttachThread(PRThreadType type,
                            PRThreadPriority priority, PRThreadStack *stack, PRUint32 flags)
{
    PRThread *thread;

    if ((thread = _PR_MD_GET_ATTACHED_THREAD()) != NULL) {
        return thread;
    }
    _PR_MD_SET_CURRENT_THREAD(NULL);

    /* Clear out any state if this thread was attached before */
    _PR_MD_SET_CURRENT_CPU(NULL);

    thread = _PR_AttachThread(type, priority, stack);
    if (thread) {
        PRIntn is;

        _PR_MD_SET_CURRENT_THREAD(thread);

        thread->flags = flags | _PR_GLOBAL_SCOPE | _PR_ATTACHED;

        if (!stack) {
            thread->stack = PR_NEWZAP(PRThreadStack);
            if (!thread->stack) {
                _PR_DestroyThread(thread);
                return NULL;
            }
            thread->stack->stackSize = _MD_DEFAULT_STACK_SIZE;
        }
        PR_INIT_CLIST(&thread->links);

        if (_PR_MD_INIT_ATTACHED_THREAD(thread) == PR_FAILURE) {
            PR_DELETE(thread->stack);
            _PR_DestroyThread(thread);
            return NULL;
        }

        _PR_MD_SET_CURRENT_CPU(NULL);

        if (_PR_MD_CURRENT_CPU()) {
            _PR_INTSOFF(is);
            PR_Lock(_pr_activeLock);
        }
        if (type == PR_SYSTEM_THREAD) {
            thread->flags |= _PR_SYSTEM;
            _pr_systemActive++;
        } else {
            _pr_userActive++;
        }
        if (_PR_MD_CURRENT_CPU()) {
            PR_Unlock(_pr_activeLock);
            _PR_INTSON(is);
        }
    }
    return thread;
}

PR_IMPLEMENT(PRThread*) PR_AttachThread(PRThreadType type,
                                        PRThreadPriority priority, PRThreadStack *stack)
{
    return PR_GetCurrentThread();
}

PR_IMPLEMENT(void) PR_DetachThread(void)
{
    /*
     * On Solaris, and Windows, foreign threads are detached when
     * they terminate.
     */
#if !defined(WIN32) \
        && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY))
    PRThread *me;
    if (_pr_initialized) {
        me = _PR_MD_GET_ATTACHED_THREAD();
        if ((me != NULL) && (me->flags & _PR_ATTACHED)) {
            _PRI_DetachThread();
        }
    }
#endif
}

void _PRI_DetachThread(void)
{
    PRThread *me = _PR_MD_CURRENT_THREAD();

    if (me->flags & _PR_PRIMORDIAL) {
        /*
         * ignore, if primordial thread
         */
        return;
    }
    PR_ASSERT(me->flags & _PR_ATTACHED);
    PR_ASSERT(_PR_IS_NATIVE_THREAD(me));
    _PR_CleanupThread(me);
    PR_DELETE(me->privateData);

    _PR_DecrActiveThreadCount(me);

    _PR_MD_CLEAN_THREAD(me);
    _PR_MD_SET_CURRENT_THREAD(NULL);
    if (!me->threadAllocatedOnStack) {
        PR_DELETE(me->stack);
    }
    _PR_MD_FREE_LOCK(&me->threadLock);
    PR_DELETE(me);
}

/*
** Wait for thread termination:
**     "thread" is the target thread
**
** This can return PR_FAILURE if no joinable thread could be found
** corresponding to the specified target thread.
**
** The calling thread is suspended until the target thread completes.
** Several threads cannot wait for the same thread to complete; one thread
** will complete successfully and others will terminate with an error PR_FAILURE.
** The calling thread will not be blocked if the target thread has already
** terminated.
*/
PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thread)
{
    PRIntn is;
    PRCondVar *term;
    PRThread *me = _PR_MD_CURRENT_THREAD();

    if (!_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSOFF(is);
    }
    term = thread->term;
    /* can't join a non-joinable thread */
    if (term == NULL) {
        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
        goto ErrorExit;
    }

    /* multiple threads can't wait on the same joinable thread */
    if (term->condQ.next != &term->condQ) {
        goto ErrorExit;
    }
    if (!_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSON(is);
    }

    /* wait for the target thread's termination cv invariant */
    PR_Lock (_pr_terminationCVLock);
    while (thread->state != _PR_JOIN_WAIT) {
        (void) PR_WaitCondVar(term, PR_INTERVAL_NO_TIMEOUT);
    }
    (void) PR_Unlock (_pr_terminationCVLock);

    /*
     Remove target thread from global waiting to join Q; make it runnable
     again and put it back on its run Q.  When it gets scheduled later in
     _PR_RunThread code, it will clean up its stack.
    */
    if (!_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSOFF(is);
    }
    thread->state = _PR_RUNNABLE;
    if ( !_PR_IS_NATIVE_THREAD(thread) ) {
        _PR_THREAD_LOCK(thread);

        _PR_MISCQ_LOCK(thread->cpu);
        _PR_DEL_JOINQ(thread);
        _PR_MISCQ_UNLOCK(thread->cpu);

        _PR_AddThreadToRunQ(me, thread);
        _PR_THREAD_UNLOCK(thread);
    }
    if (!_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSON(is);
    }

    _PR_MD_WAKEUP_WAITER(thread);

    return PR_SUCCESS;

ErrorExit:
    if ( !_PR_IS_NATIVE_THREAD(me)) {
        _PR_INTSON(is);
    }
    return PR_FAILURE;
}

PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thread,
                                        PRThreadPriority newPri)
{

    /*
    First, pin down the priority.  Not all compilers catch passing out of
    range enum here.  If we let bad values thru, priority queues won't work.
    */
    if ((PRIntn)newPri > (PRIntn)PR_PRIORITY_LAST) {
        newPri = PR_PRIORITY_LAST;
    } else if ((PRIntn)newPri < (PRIntn)PR_PRIORITY_FIRST) {
        newPri = PR_PRIORITY_FIRST;
    }

    if ( _PR_IS_NATIVE_THREAD(thread) ) {
        thread->priority = newPri;
        _PR_MD_SET_PRIORITY(&(thread->md), newPri);
    } else {
        _PR_SetThreadPriority(thread, newPri);
    }
}

PR_IMPLEMENT(PRStatus) PR_SetCurrentThreadName(const char *name)
{
    PRThread *thread;
    size_t nameLen;

    if (!name) {
        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
        return PR_FAILURE;
    }

    thread = PR_GetCurrentThread();
    if (!thread) {
        return PR_FAILURE;
    }

    PR_Free(thread->name);
    nameLen = strlen(name);
    thread->name = (char *)PR_Malloc(nameLen + 1);
    if (!thread->name) {
        return PR_FAILURE;
    }
    memcpy(thread->name, name, nameLen + 1);
    _PR_MD_SET_CURRENT_THREAD_NAME(thread->name);
    return PR_SUCCESS;
}

PR_IMPLEMENT(const char *) PR_GetThreadName(const PRThread *thread)
{
    if (!thread) {
        return NULL;
    }
    return thread->name;
}


/*
** This routine prevents all other threads from running. This call is needed by
** the garbage collector.
*/
PR_IMPLEMENT(void) PR_SuspendAll(void)
{
    PRThread *me = _PR_MD_CURRENT_THREAD();
    PRCList *qp;

    /*
     * Stop all user and native threads which are marked GC able.
     */
    PR_Lock(_pr_activeLock);
    suspendAllOn = PR_TRUE;
    suspendAllThread = _PR_MD_CURRENT_THREAD();
    _PR_MD_BEGIN_SUSPEND_ALL();
    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
         qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) {
        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) &&
            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) {
            _PR_Suspend(_PR_ACTIVE_THREAD_PTR(qp));
            PR_ASSERT((_PR_ACTIVE_THREAD_PTR(qp))->state != _PR_RUNNING);
        }
    }
    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
         qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) {
        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) &&
            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp)))
            /* PR_Suspend(_PR_ACTIVE_THREAD_PTR(qp)); */
        {
            _PR_MD_SUSPEND_THREAD(_PR_ACTIVE_THREAD_PTR(qp));
        }
    }
    _PR_MD_END_SUSPEND_ALL();
}

/*
** This routine unblocks all other threads that were suspended from running by
** PR_SuspendAll(). This call is needed by the garbage collector.
*/
PR_IMPLEMENT(void) PR_ResumeAll(void)
{
    PRThread *me = _PR_MD_CURRENT_THREAD();
    PRCList *qp;

    /*
     * Resume all user and native threads which are marked GC able.
     */
    _PR_MD_BEGIN_RESUME_ALL();
    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
         qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) {
        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) &&
            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) {
            _PR_Resume(_PR_ACTIVE_THREAD_PTR(qp));
        }
    }
    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
         qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) {
        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) &&
            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) {
            _PR_MD_RESUME_THREAD(_PR_ACTIVE_THREAD_PTR(qp));
        }
    }
    _PR_MD_END_RESUME_ALL();
    suspendAllThread = NULL;
    suspendAllOn = PR_FALSE;
    PR_Unlock(_pr_activeLock);
}

PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg)
{
    PRCList *qp, *qp_next;
    PRIntn i = 0;
    PRStatus rv = PR_SUCCESS;
    PRThread* t;

    /*
    ** Currently Enumerate threads happen only with suspension and
    ** pr_activeLock held
    */
    PR_ASSERT(suspendAllOn);

    /* Steve Morse, 4-23-97: Note that we can't walk a queue by taking
     * qp->next after applying the function "func".  In particular, "func"
     * might remove the thread from the queue and put it into another one in
     * which case qp->next no longer points to the next entry in the original
     * queue.
     *
     * To get around this problem, we save qp->next in qp_next before applying
     * "func" and use that saved value as the next value after applying "func".
     */

    /*
     * Traverse the list of local and global threads
     */
    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
         qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp_next)
    {
        qp_next = qp->next;
        t = _PR_ACTIVE_THREAD_PTR(qp);
        if (_PR_IS_GCABLE_THREAD(t))
        {
            rv = (*func)(t, i, arg);
            if (rv != PR_SUCCESS) {
                return rv;
            }
            i++;
        }
    }
    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
         qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp_next)
    {
        qp_next = qp->next;
        t = _PR_ACTIVE_THREAD_PTR(qp);
        if (_PR_IS_GCABLE_THREAD(t))
        {
            rv = (*func)(t, i, arg);
            if (rv != PR_SUCCESS) {
                return rv;
            }
            i++;
        }
    }
    return rv;
}

/* FUNCTION: _PR_AddSleepQ
** DESCRIPTION:
**    Adds a thread to the sleep/pauseQ.
** RESTRICTIONS:
**    Caller must have the RUNQ lock.
**    Caller must be a user level thread
*/
PR_IMPLEMENT(void)
_PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout)
{
    _PRCPU *cpu = thread->cpu;

    if (timeout == PR_INTERVAL_NO_TIMEOUT) {
        /* append the thread to the global pause Q */
        PR_APPEND_LINK(&thread->links, &_PR_PAUSEQ(thread->cpu));
        thread->flags |= _PR_ON_PAUSEQ;
    } else {
        PRIntervalTime sleep;
        PRCList *q;
        PRThread *t;

        /* sort onto global sleepQ */
        sleep = timeout;

        /* Check if we are longest timeout */
        if (timeout >= _PR_SLEEPQMAX(cpu)) {
            PR_INSERT_BEFORE(&thread->links, &_PR_SLEEPQ(cpu));
            thread->sleep = timeout - _PR_SLEEPQMAX(cpu);
            _PR_SLEEPQMAX(cpu) = timeout;
        } else {
            /* Sort thread into global sleepQ at appropriate point */
            q = _PR_SLEEPQ(cpu).next;

            /* Now scan the list for where to insert this entry */
            while (q != &_PR_SLEEPQ(cpu)) {
                t = _PR_THREAD_PTR(q);
                if (sleep < t->sleep) {
                    /* Found sleeper to insert in front of */
                    break;
                }
                sleep -= t->sleep;
                q = q->next;
            }
            thread->sleep = sleep;
            PR_INSERT_BEFORE(&thread->links, q);

            /*
            ** Subtract our sleep time from the sleeper that follows us (there
            ** must be one) so that they remain relative to us.
            */
            PR_ASSERT (thread->links.next != &_PR_SLEEPQ(cpu));

            t = _PR_THREAD_PTR(thread->links.next);
            PR_ASSERT(_PR_THREAD_PTR(t->links.prev) == thread);
            t->sleep -= sleep;
        }

        thread->flags |= _PR_ON_SLEEPQ;
    }
}

/* FUNCTION: _PR_DelSleepQ
** DESCRIPTION:
**    Removes a thread from the sleep/pauseQ.
** INPUTS:
**    If propogate_time is true, then the thread following the deleted
**    thread will be get the time from the deleted thread.  This is used
**    when deleting a sleeper that has not timed out.
** RESTRICTIONS:
**    Caller must have the RUNQ lock.
**    Caller must be a user level thread
*/
PR_IMPLEMENT(void)
_PR_DelSleepQ(PRThread *thread, PRBool propogate_time)
{
    _PRCPU *cpu = thread->cpu;

    /* Remove from pauseQ/sleepQ */
    if (thread->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
        if (thread->flags & _PR_ON_SLEEPQ) {
            PRCList *q = thread->links.next;
            if (q != &_PR_SLEEPQ(cpu)) {
                if (propogate_time == PR_TRUE) {
                    PRThread *after = _PR_THREAD_PTR(q);
                    after->sleep += thread->sleep;
                } else {
                    _PR_SLEEPQMAX(cpu) -= thread->sleep;
                }
            } else {
                /* Check if prev is the beggining of the list; if so,
                 * we are the only element on the list.
                 */
                if (thread->links.prev != &_PR_SLEEPQ(cpu)) {
                    _PR_SLEEPQMAX(cpu) -= thread->sleep;
                }
                else {
                    _PR_SLEEPQMAX(cpu) = 0;
                }
            }
            thread->flags &= ~_PR_ON_SLEEPQ;
        } else {
            thread->flags &= ~_PR_ON_PAUSEQ;
        }
        PR_REMOVE_LINK(&thread->links);
    } else {
        PR_ASSERT(0);
    }
}

void
_PR_AddThreadToRunQ(
    PRThread *me,     /* the current thread */
    PRThread *thread) /* the local thread to be added to a run queue */
{
    PRThreadPriority pri = thread->priority;
    _PRCPU *cpu = thread->cpu;

    PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread));

#if defined(WINNT)
    /*
     * On NT, we can only reliably know that the current CPU
     * is not idle.  We add the awakened thread to the run
     * queue of its CPU if its CPU is the current CPU.
     * For any other CPU, we don't really know whether it
     * is busy or idle.  So in all other cases, we just
     * "post" the awakened thread to the IO completion port
     * for the next idle CPU to execute (this is done in
     * _PR_MD_WAKEUP_WAITER).
     * Threads with a suspended I/O operation remain bound to
     * the same cpu until I/O is cancelled
     *
     * NOTE: the boolean expression below must be the exact
     * opposite of the corresponding boolean expression in
     * _PR_MD_WAKEUP_WAITER.
     */
    if ((!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) ||
        (thread->md.thr_bound_cpu)) {
        PR_ASSERT(!thread->md.thr_bound_cpu ||
                  (thread->md.thr_bound_cpu == cpu));
        _PR_RUNQ_LOCK(cpu);
        _PR_ADD_RUNQ(thread, cpu, pri);
        _PR_RUNQ_UNLOCK(cpu);
    }
#else
    _PR_RUNQ_LOCK(cpu);
    _PR_ADD_RUNQ(thread, cpu, pri);
    _PR_RUNQ_UNLOCK(cpu);
    if (!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) {
        if (pri > me->priority) {
            _PR_SET_RESCHED_FLAG();
        }
    }
#endif
}
