/* -*- 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"

/* List of free stack virtual memory chunks */
PRLock *_pr_stackLock;
PRCList _pr_freeStacks = PR_INIT_STATIC_CLIST(&_pr_freeStacks);
PRIntn _pr_numFreeStacks;
PRIntn _pr_maxFreeStacks = 4;

#ifdef DEBUG
/*
** A variable that can be set via the debugger...
*/
PRBool _pr_debugStacks = PR_FALSE;
#endif

/* How much space to leave between the stacks, at each end */
#define REDZONE		(2 << _pr_pageShift)

#define _PR_THREAD_STACK_PTR(_qp) \
    ((PRThreadStack*) ((char*) (_qp) - offsetof(PRThreadStack,links)))

void _PR_InitStacks(void)
{
    _pr_stackLock = PR_NewLock();
}

void _PR_CleanupStacks(void)
{
    if (_pr_stackLock) {
        PR_DestroyLock(_pr_stackLock);
        _pr_stackLock = NULL;
    }
}

/*
** Allocate a stack for a thread.
*/
PRThreadStack *_PR_NewStack(PRUint32 stackSize)
{
    PRCList *qp;
    PRThreadStack *ts;
    PRThread *thr;

    /*
    ** Trim the list of free stacks. Trim it backwards, tossing out the
    ** oldest stack found first (this way more recent stacks have a
    ** chance of being present in the data cache).
    */
    PR_Lock(_pr_stackLock);
    qp = _pr_freeStacks.prev;
    while ((_pr_numFreeStacks > _pr_maxFreeStacks) && (qp != &_pr_freeStacks)) {
	ts = _PR_THREAD_STACK_PTR(qp);
	thr = _PR_THREAD_STACK_TO_PTR(ts);
	qp = qp->prev;
	/*
	 * skip stacks which are still being used
	 */
	if (thr->no_sched)
		continue;
	PR_REMOVE_LINK(&ts->links);

	/* Give platform OS to clear out the stack for debugging */
	_PR_MD_CLEAR_STACK(ts);

	_pr_numFreeStacks--;
	_PR_DestroySegment(ts->seg);
	PR_DELETE(ts);
    }

    /*
    ** Find a free thread stack. This searches the list of free'd up
    ** virtually mapped thread stacks.
    */
    qp = _pr_freeStacks.next;
    ts = 0;
    while (qp != &_pr_freeStacks) {
	ts = _PR_THREAD_STACK_PTR(qp);
	thr = _PR_THREAD_STACK_TO_PTR(ts);
	qp = qp->next;
	/*
	 * skip stacks which are still being used
	 */
	if ((!(thr->no_sched)) && ((ts->allocSize - 2*REDZONE) >= stackSize)) {
	    /*
	    ** Found a stack that is not in use and is big enough. Change
	    ** stackSize to fit it.
	    */
	    stackSize = ts->allocSize - 2*REDZONE;
	    PR_REMOVE_LINK(&ts->links);
	    _pr_numFreeStacks--;
	    ts->links.next = 0;
	    ts->links.prev = 0;
	    PR_Unlock(_pr_stackLock);
	    goto done;
	}
	ts = 0;
    }
    PR_Unlock(_pr_stackLock);

    if (!ts) {
	/* Make a new thread stack object. */
	ts = PR_NEWZAP(PRThreadStack);
	if (!ts) {
	    return NULL;
	}

	/*
	** Assign some of the virtual space to the new stack object. We
	** may not get that piece of VM, but if nothing else we will
	** advance the pointer so we don't collide (unless the OS screws
	** up).
	*/
	ts->allocSize = stackSize + 2*REDZONE;
	ts->seg = _PR_NewSegment(ts->allocSize, 0);
	if (!ts->seg) {
	    PR_DELETE(ts);
	    return NULL;
	}
	}

  done:
    ts->allocBase = (char*)ts->seg->vaddr;
    ts->flags = _PR_STACK_MAPPED;
    ts->stackSize = stackSize;

#ifdef HAVE_STACK_GROWING_UP
    ts->stackTop = ts->allocBase + REDZONE;
    ts->stackBottom = ts->stackTop + stackSize;
#else
    ts->stackBottom = ts->allocBase + REDZONE;
    ts->stackTop = ts->stackBottom + stackSize;
#endif

    PR_LOG(_pr_thread_lm, PR_LOG_NOTICE,
	   ("thread stack: base=0x%x limit=0x%x bottom=0x%x top=0x%x\n",
	    ts->allocBase, ts->allocBase + ts->allocSize - 1,
	    ts->allocBase + REDZONE,
	    ts->allocBase + REDZONE + stackSize - 1));
	    
    _PR_MD_INIT_STACK(ts,REDZONE);

    return ts;
}

/*
** Free the stack for the current thread
*/
void _PR_FreeStack(PRThreadStack *ts)
{
    if (!ts) {
	return;
    }
    if (ts->flags & _PR_STACK_PRIMORDIAL) {
	PR_DELETE(ts);
	return;
    }

    /*
    ** Put the stack on the free list. This is done because we are still
    ** using the stack. Next time a thread is created we will trim the
    ** list down; it's safe to do it then because we will have had to
    ** context switch to a live stack before another thread can be
    ** created.
    */
    PR_Lock(_pr_stackLock);
    PR_APPEND_LINK(&ts->links, _pr_freeStacks.prev);
    _pr_numFreeStacks++;
    PR_Unlock(_pr_stackLock);
}
