/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Netscape Portable Runtime (NSPR).
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "primpl.h"

_PRCPU *_pr_primordialCPU = NULL;

PRInt32 _pr_md_idle_cpus;       /* number of idle cpus */
/*
 * The idle threads in MxN models increment/decrement _pr_md_idle_cpus.
 * If _PR_HAVE_ATOMIC_OPS is not defined, they can't use the atomic
 * increment/decrement routines (which are based on PR_Lock/PR_Unlock),
 * because PR_Lock asserts that the calling thread is not an idle thread.
 * So we use a _MDLock to protect _pr_md_idle_cpus.
 */
#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
#ifndef _PR_HAVE_ATOMIC_OPS
static _MDLock _pr_md_idle_cpus_lock;
#endif
#endif
PRUintn _pr_numCPU;
PRInt32 _pr_cpus_exit;
PRInt32 _pr_cpu_affinity_mask = 0;

#if !defined (_PR_GLOBAL_THREADS_ONLY)

static PRUintn _pr_cpuID;

static void PR_CALLBACK _PR_CPU_Idle(void *);

static _PRCPU *_PR_CreateCPU(void);
static PRStatus _PR_StartCPU(_PRCPU *cpu, PRThread *thread);

#if !defined(_PR_LOCAL_THREADS_ONLY)
static void _PR_RunCPU(void *arg);
#endif

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

    if (_native_threads_only)
        return;

    _pr_cpuID = 0;
    _MD_NEW_LOCK( &_pr_cpuLock);
#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
#ifndef _PR_HAVE_ATOMIC_OPS
    _MD_NEW_LOCK(&_pr_md_idle_cpus_lock);
#endif
#endif

#ifdef _PR_LOCAL_THREADS_ONLY

#ifdef HAVE_CUSTOM_USER_THREADS
    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(me);
#endif

    /* Now start the first CPU. */
    _pr_primordialCPU = _PR_CreateCPU();
    _pr_numCPU = 1;
    _PR_StartCPU(_pr_primordialCPU, me);

    _PR_MD_SET_CURRENT_CPU(_pr_primordialCPU);

    /* Initialize cpu for current thread (could be different from me) */
    _PR_MD_CURRENT_THREAD()->cpu = _pr_primordialCPU;

    _PR_MD_SET_LAST_THREAD(me);

#else /* Combined MxN model */

    _pr_primordialCPU = _PR_CreateCPU();
    _pr_numCPU = 1;
    _PR_CreateThread(PR_SYSTEM_THREAD,
                     _PR_RunCPU,
                     _pr_primordialCPU,
                     PR_PRIORITY_NORMAL,
                     PR_GLOBAL_THREAD,
                     PR_UNJOINABLE_THREAD,
                     0,
                     _PR_IDLE_THREAD);

#endif /* _PR_LOCAL_THREADS_ONLY */

    _PR_MD_INIT_CPUS();
}

#ifdef WINNT
/*
 * Right now this function merely stops the CPUs and does
 * not do any other cleanup.
 *
 * It is only implemented for WINNT because bug 161998 only
 * affects the WINNT version of NSPR, but it would be nice
 * to implement this function for other platforms too.
 */
void _PR_CleanupCPUs(void)
{
    PRUintn i;
    PRCList *qp;
    _PRCPU *cpu;

    _pr_cpus_exit = 1;
    for (i = 0; i < _pr_numCPU; i++) {
        _PR_MD_WAKEUP_WAITER(NULL);
    }
    for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
        cpu = _PR_CPU_PTR(qp);
        _PR_MD_JOIN_THREAD(&cpu->thread->md);
    }
}
#endif

static _PRCPUQueue *_PR_CreateCPUQueue(void)
{
    PRInt32 index;
    _PRCPUQueue *cpuQueue;
    cpuQueue = PR_NEWZAP(_PRCPUQueue);
 
    _MD_NEW_LOCK( &cpuQueue->runQLock );
    _MD_NEW_LOCK( &cpuQueue->sleepQLock );
    _MD_NEW_LOCK( &cpuQueue->miscQLock );

    for (index = 0; index < PR_PRIORITY_LAST + 1; index++)
        PR_INIT_CLIST( &(cpuQueue->runQ[index]) );
    PR_INIT_CLIST( &(cpuQueue->sleepQ) );
    PR_INIT_CLIST( &(cpuQueue->pauseQ) );
    PR_INIT_CLIST( &(cpuQueue->suspendQ) );
    PR_INIT_CLIST( &(cpuQueue->waitingToJoinQ) );

    cpuQueue->numCPUs = 1;

    return cpuQueue;
}

/*
 * Create a new CPU.
 *
 * This function initializes enough of the _PRCPU structure so
 * that it can be accessed safely by a global thread or another
 * CPU.  This function does not create the native thread that
 * will run the CPU nor does it initialize the parts of _PRCPU
 * that must be initialized by that native thread.
 *
 * The reason we cannot simply have the native thread create
 * and fully initialize a new CPU is that we need to be able to
 * create a usable _pr_primordialCPU in _PR_InitCPUs without
 * assuming that the primordial CPU thread we created can run
 * during NSPR initialization.  For example, on Windows while
 * new threads can be created by DllMain, they won't be able
 * to run during DLL initialization.  If NSPR is initialized
 * by DllMain, the primordial CPU thread won't run until DLL
 * initialization is finished.
 */
static _PRCPU *_PR_CreateCPU(void)
{
    _PRCPU *cpu;

    cpu = PR_NEWZAP(_PRCPU);
    if (cpu) {
        cpu->queue = _PR_CreateCPUQueue();
        if (!cpu->queue) {
            PR_DELETE(cpu);
            return NULL;
        }
    }
    return cpu;
}

/*
 * Start a new CPU.
 *
 * 'cpu' is a _PRCPU structure created by _PR_CreateCPU().
 * 'thread' is the native thread that will run the CPU.
 *
 * If this function fails, 'cpu' is destroyed.
 */
static PRStatus _PR_StartCPU(_PRCPU *cpu, PRThread *thread)
{
    /*
    ** Start a new cpu. The assumption this code makes is that the
    ** underlying operating system creates a stack to go with the new
    ** native thread. That stack will be used by the cpu when pausing.
    */

    PR_ASSERT(!_native_threads_only);

    cpu->last_clock = PR_IntervalNow();

    /* Before we create any threads on this CPU we have to
     * set the current CPU 
     */
    _PR_MD_SET_CURRENT_CPU(cpu);
    _PR_MD_INIT_RUNNING_CPU(cpu);
    thread->cpu = cpu;

    cpu->idle_thread = _PR_CreateThread(PR_SYSTEM_THREAD,
                                        _PR_CPU_Idle,
                                        (void *)cpu,
                                        PR_PRIORITY_NORMAL,
                                        PR_LOCAL_THREAD,
                                        PR_UNJOINABLE_THREAD,
                                        0,
                                        _PR_IDLE_THREAD);

    if (!cpu->idle_thread) {
        /* didn't clean up CPU queue XXXMB */
        PR_DELETE(cpu);
        return PR_FAILURE;
    } 
    PR_ASSERT(cpu->idle_thread->cpu == cpu);

    cpu->idle_thread->no_sched = 0;

    cpu->thread = thread;

    if (_pr_cpu_affinity_mask)
        PR_SetThreadAffinityMask(thread, _pr_cpu_affinity_mask);

    /* Created and started a new CPU */
    _PR_CPU_LIST_LOCK();
    cpu->id = _pr_cpuID++;
    PR_APPEND_LINK(&cpu->links, &_PR_CPUQ());
    _PR_CPU_LIST_UNLOCK();

    return PR_SUCCESS;
}

#if !defined(_PR_GLOBAL_THREADS_ONLY) && !defined(_PR_LOCAL_THREADS_ONLY)
/*
** This code is used during a cpu's initial creation.
*/
static void _PR_RunCPU(void *arg)
{
    _PRCPU *cpu = (_PRCPU *)arg;
    PRThread *me = _PR_MD_CURRENT_THREAD();

    PR_ASSERT(NULL != me);

    /*
     * _PR_StartCPU calls _PR_CreateThread to create the
     * idle thread.  Because _PR_CreateThread calls PR_Lock,
     * the current thread has to remain a global thread
     * during the _PR_StartCPU call so that it can wait for
     * the lock if the lock is held by another thread.  If
     * we clear the _PR_GLOBAL_SCOPE flag in
     * _PR_MD_CREATE_PRIMORDIAL_THREAD, the current thread
     * will be treated as a local thread and have trouble
     * waiting for the lock because the CPU is not fully
     * constructed yet.
     *
     * After the CPU is started, it is safe to mark the
     * current thread as a local thread.
     */

#ifdef HAVE_CUSTOM_USER_THREADS
    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(me);
#endif

    me->no_sched = 1;
    _PR_StartCPU(cpu, me);

#ifdef HAVE_CUSTOM_USER_THREADS
    me->flags &= (~_PR_GLOBAL_SCOPE);
#endif

    _PR_MD_SET_CURRENT_CPU(cpu);
    _PR_MD_SET_CURRENT_THREAD(cpu->thread);
    me->cpu = cpu;

    while(1) {
        PRInt32 is;
        if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
	    _PR_MD_START_INTERRUPTS();
        _PR_MD_SWITCH_CONTEXT(me);
    }
}
#endif

static void PR_CALLBACK _PR_CPU_Idle(void *_cpu)
{
    _PRCPU *cpu = (_PRCPU *)_cpu;
    PRThread *me = _PR_MD_CURRENT_THREAD();

    PR_ASSERT(NULL != me);

    me->cpu = cpu;
    cpu->idle_thread = me;
    if (_MD_LAST_THREAD())
        _MD_LAST_THREAD()->no_sched = 0;
    if (!_PR_IS_NATIVE_THREAD(me)) _PR_MD_SET_INTSOFF(0);
    while(1) {
        PRInt32 is;
        PRIntervalTime timeout;
        if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);

        _PR_RUNQ_LOCK(cpu);
#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
#ifdef _PR_HAVE_ATOMIC_OPS
        _PR_MD_ATOMIC_INCREMENT(&_pr_md_idle_cpus);
#else
        _PR_MD_LOCK(&_pr_md_idle_cpus_lock);
        _pr_md_idle_cpus++;
        _PR_MD_UNLOCK(&_pr_md_idle_cpus_lock);
#endif /* _PR_HAVE_ATOMIC_OPS */
#endif
        /* If someone on runq; do a nonblocking PAUSECPU */
        if (_PR_RUNQREADYMASK(me->cpu) != 0) {
            _PR_RUNQ_UNLOCK(cpu);
            timeout = PR_INTERVAL_NO_WAIT;
        } else {
            _PR_RUNQ_UNLOCK(cpu);

            _PR_SLEEPQ_LOCK(cpu);
            if (PR_CLIST_IS_EMPTY(&_PR_SLEEPQ(me->cpu))) {
                timeout = PR_INTERVAL_NO_TIMEOUT;
            } else {
                PRThread *wakeThread;
                wakeThread = _PR_THREAD_PTR(_PR_SLEEPQ(me->cpu).next);
                timeout = wakeThread->sleep;
            }
            _PR_SLEEPQ_UNLOCK(cpu);
        }

        /* Wait for an IO to complete */
        (void)_PR_MD_PAUSE_CPU(timeout);

#ifdef WINNT
        if (_pr_cpus_exit) {
            /* _PR_CleanupCPUs tells us to exit */
            _PR_MD_END_THREAD();
        }
#endif

#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
#ifdef _PR_HAVE_ATOMIC_OPS
        _PR_MD_ATOMIC_DECREMENT(&_pr_md_idle_cpus);
#else
        _PR_MD_LOCK(&_pr_md_idle_cpus_lock);
        _pr_md_idle_cpus--;
        _PR_MD_UNLOCK(&_pr_md_idle_cpus_lock);
#endif /* _PR_HAVE_ATOMIC_OPS */
#endif

		_PR_ClockInterrupt();

		/* Now schedule any thread that is on the runq
		 * INTS must be OFF when calling PR_Schedule()
		 */
		me->state = _PR_RUNNABLE;
		_PR_MD_SWITCH_CONTEXT(me);
		if (!_PR_IS_NATIVE_THREAD(me)) _PR_FAST_INTSON(is);
    }
}
#endif /* _PR_GLOBAL_THREADS_ONLY */

PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs)
{
#if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_LOCAL_THREADS_ONLY)

    /* do nothing */

#else /* combined, MxN thread model */

    PRUintn newCPU;
    _PRCPU *cpu;
    PRThread *thr;


    if (!_pr_initialized) _PR_ImplicitInitialization();

	if (_native_threads_only)
		return;
    
    _PR_CPU_LIST_LOCK();
    if (_pr_numCPU < numCPUs) {
        newCPU = numCPUs - _pr_numCPU;
        _pr_numCPU = numCPUs;
    } else newCPU = 0;
    _PR_CPU_LIST_UNLOCK();

    for (; newCPU; newCPU--) {
        cpu = _PR_CreateCPU();
        thr = _PR_CreateThread(PR_SYSTEM_THREAD,
                              _PR_RunCPU,
                              cpu,
                              PR_PRIORITY_NORMAL,
                              PR_GLOBAL_THREAD,
                              PR_UNJOINABLE_THREAD,
                              0,
                              _PR_IDLE_THREAD);
    }
#endif
}

PR_IMPLEMENT(_PRCPU *) _PR_GetPrimordialCPU(void)
{
    if (_pr_primordialCPU)
        return _pr_primordialCPU;
    else
        return _PR_MD_CURRENT_CPU();
}
