Index: mozilla/nsprpub/pr/src/threads/combined/prustack.c |
=================================================================== |
--- mozilla/nsprpub/pr/src/threads/combined/prustack.c (revision 191424) |
+++ mozilla/nsprpub/pr/src/threads/combined/prustack.c (working copy) |
@@ -1,174 +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" |
- |
-/* 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); |
-} |