diff options
| author | Miguel Sofer <miguel.sofer@gmail.com> | 2008-07-13 09:03:31 (GMT) | 
|---|---|---|
| committer | Miguel Sofer <miguel.sofer@gmail.com> | 2008-07-13 09:03:31 (GMT) | 
| commit | cbd9b876ccfb24791ac9576e49be51c579fa7a23 (patch) | |
| tree | 7d872fa5186b327990fa96d969a3b092780f38d2 /unix/tclUnixInit.c | |
| parent | 2603994d5d3ad503d97298c7fd1dc8f528694a19 (diff) | |
| download | tcl-cbd9b876ccfb24791ac9576e49be51c579fa7a23.zip tcl-cbd9b876ccfb24791ac9576e49be51c579fa7a23.tar.gz tcl-cbd9b876ccfb24791ac9576e49be51c579fa7a23.tar.bz2 | |
NRE implementation [Patch 2017110]
Diffstat (limited to 'unix/tclUnixInit.c')
| -rw-r--r-- | unix/tclUnixInit.c | 259 | 
1 files changed, 1 insertions, 258 deletions
| diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index 4c8427d..0b3cdc9 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -7,7 +7,7 @@   * Copyright (c) 1999 by Scriptics Corporation.   * All rights reserved.   * - * RCS: @(#) $Id: tclUnixInit.c,v 1.83 2008/04/27 22:21:35 dkf Exp $ + * RCS: @(#) $Id: tclUnixInit.c,v 1.84 2008/07/13 09:03:41 msofer Exp $   */  #include "tclInt.h" @@ -38,64 +38,6 @@  #endif  /* - * Define TCL_NO_STACK_CHECK in the compiler options if you want to revert to - * the old behavior of never checking the stack. - */ - -/* - * Define this if you want to see a lot of output regarding stack checking. - */ - -#undef TCL_DEBUG_STACK_CHECK - -/* - * Values used to compute how much space is really available for Tcl's use for - * the stack. - * - * The getrlimit() function is documented to return the maximum stack size in - * bytes. However, with threads enabled, the pthread library on some platforms - * does bad things to the stack size limits. First, the limits cannot be - * changed. Second, they appear to be sometimes reported incorrectly. - * - * The defines below may need to be adjusted if more platforms have this - * broken behavior with threads enabled. - */ - -#ifndef TCL_MAGIC_STACK_DIVISOR -#define TCL_MAGIC_STACK_DIVISOR		1 -#endif -#ifndef TCL_RESERVED_STACK_PAGES -#define TCL_RESERVED_STACK_PAGES	8 -#endif - -/* - * Thread specific data for stack checking. - */ - -#ifndef TCL_NO_STACK_CHECK -typedef struct ThreadSpecificData { -    int *outerVarPtr;		/* The "outermost" stack frame pointer for -				 * this thread. */ -    int *stackBound;            /* The current stack boundary */ -} ThreadSpecificData; -static Tcl_ThreadDataKey dataKey; -#ifdef TCL_CROSS_COMPILE -static int stackGrowsDown = -1; -static int StackGrowsDown(int *parent); -#elif defined(TCL_STACK_GROWS_UP) -#define stackGrowsDown 0 -#else -#define stackGrowsDown 1 -#endif -#endif /* TCL_NO_STACK_CHECK */ - -#ifdef TCL_DEBUG_STACK_CHECK -#define STACK_DEBUG(args) printf args -#else -#define STACK_DEBUG(args) (void)0 -#endif /* TCL_DEBUG_STACK_CHECK */ - -/*   * Tcl tries to use standard and homebrew methods to guess the right encoding   * on the platform. However, there is always a final fallback, and this value   * is it. Make sure it is a real Tcl encoding. @@ -327,9 +269,6 @@ static const LocaleTable localeTable[] = {  		    {"zh_tw.big5",	"big5"},  }; -#ifndef TCL_NO_STACK_CHECK -static int		GetStackSize(size_t *stackSizePtr); -#endif /* TCL_NO_STACK_CHECK */  #ifdef HAVE_COREFOUNDATION  static int		MacOSXGetLibraryPath(Tcl_Interp *interp,  			    int maxPathLen, char *tclLibPath); @@ -1008,202 +947,6 @@ TclpFindVariable(      return result;  } -#ifndef TCL_NO_STACK_CHECK -/* - *---------------------------------------------------------------------- - * - * TclpGetCStackParams -- - * - *	Determine the stack params for the current thread: in which - *	direction does the stack grow, and what is the stack lower (resp. - *	upper) bound for safe invocation of a new command? This is used to - *	cache the values needed for an efficient computation of - *	TclpCheckStackSpace() when the interp is known. - * - * Results: - *	Returns 1 if the stack grows down, in which case a stack lower bound - *	is stored at stackBoundPtr. If the stack grows up, 0 is returned and - *	an upper bound is stored at stackBoundPtr. If a bound cannot be - *	determined NULL is stored at stackBoundPtr. - * - *---------------------------------------------------------------------- - */ - -int -TclpGetCStackParams( -    int **stackBoundPtr) -{ -    int result = TCL_OK; -    size_t stackSize = 0;	/* The size of the current stack. */ -    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); -				/* Most variables are actually in a -				 * thread-specific data block to minimise the -				 * impact on the stack. */ -#ifdef TCL_CROSS_COMPILE -    if (stackGrowsDown == -1) { -	/* -	 * Not initialised! -	 */ - -	stackGrowsDown = StackGrowsDown(&result); -    } -#endif -     -    /* -     * The first time through in a thread: record the "outermost" stack -     * frame and inquire with the OS about the stack size. -     */ - -    if (tsdPtr->outerVarPtr == NULL) { -	tsdPtr->outerVarPtr = &result; -	result = GetStackSize(&stackSize); -	if (result != TCL_OK) { -	    /* Can't check, assume it always succeeds */ -#ifdef TCL_CROSS_COMPILE -	    stackGrowsDown = 1; -#endif -	    tsdPtr->stackBound = NULL; -	    goto done; -	} -    } - -    if (stackSize || (tsdPtr->stackBound && -	    ((stackGrowsDown && (&result < tsdPtr->stackBound)) || -	    (!stackGrowsDown && (&result > tsdPtr->stackBound))))) { -	/* -	 * Either the thread's first pass or stack failure: set the params -	 */ - -	if (!stackSize) { -	    /* -	     * Stack failure: if we didn't already blow up, we are within the -	     * safety area. Recheck with the OS in case the stack was grown.  -	     */ -	    result = GetStackSize(&stackSize); -	    if (result != TCL_OK) { -		/* Can't check, assume it always succeeds */ -#ifdef TCL_CROSS_COMPILE -		stackGrowsDown = 1; -#endif -		tsdPtr->stackBound = NULL; -		goto done; -	    } -	} - -	if (stackGrowsDown) { -	    tsdPtr->stackBound = (int *) ((char *)tsdPtr->outerVarPtr - -		    stackSize); -	} else { -	    tsdPtr->stackBound = (int *) ((char *)tsdPtr->outerVarPtr + -		    stackSize); -	} -    } - -    done: -    *stackBoundPtr = tsdPtr->stackBound; -    return stackGrowsDown; -} - -#ifdef TCL_CROSS_COMPILE -int -StackGrowsDown( -    int *parent) -{ -    int here; -    return (&here < parent); -} -#endif - -/* - *---------------------------------------------------------------------- - * - * GetStackSize -- - * - *	Discover what the stack size for the current thread/process actually - *	is. Expects to only ever be called once per thread and then only at a - *	point when there is a reasonable amount of space left on the current - *	stack; TclpCheckStackSpace is called sufficiently frequently that that - *	is true. - * - * Results: - *	TCL_OK if the stack space was discovered, TCL_BREAK if the stack space - *	was undiscoverable in a way that stack checks should fail, and - *	TCL_CONTINUE if the stack space was undiscoverable in a way that stack - *	checks should succeed. - * - * Side effects: - *	None - * - *---------------------------------------------------------------------- - */ - -static int -GetStackSize( -    size_t *stackSizePtr) -{ -    size_t rawStackSize; -    struct rlimit rLimit;	/* The result from getrlimit(). */ - -#ifdef TCL_THREADS -    rawStackSize = TclpThreadGetStackSize(); -    if (rawStackSize == (size_t) -1) { -	/* -	 * Some kind of confirmed error in TclpThreadGetStackSize?! Fall back -	 * to whatever getrlimit can determine. -	 */ -	STACK_DEBUG(("stack checks: TclpThreadGetStackSize failed in \n")); -    } -    if (rawStackSize > 0) { -	goto finalSanityCheck; -    } - -    /* -     * If we have zero or an error, try the system limits instead. After all, -     * the pthread documentation states that threads should always be bound by -     * the system stack size limit in any case. -     */ -#endif /* TCL_THREADS */ - -    if (getrlimit(RLIMIT_STACK, &rLimit) != 0) { -	/* -	 * getrlimit() failed, just fail the whole thing. -	 */ -	STACK_DEBUG(("skipping stack checks with failure: getrlimit failed\n")); -	return TCL_BREAK; -    } -    if (rLimit.rlim_cur == RLIM_INFINITY) { -	/* -	 * Limit is "infinite"; there is no stack limit. -	 */ -	STACK_DEBUG(("skipping stack checks with success: infinite limit\n")); -	return TCL_CONTINUE; -    } -    rawStackSize = rLimit.rlim_cur; - -    /* -     * Final sanity check on the determined stack size. If we fail this, -     * assume there are bogus values about and that we can't actually figure -     * out what the stack size really is. -     */ - -#ifdef TCL_THREADS /* Stop warning... */ -  finalSanityCheck: -#endif -    if (rawStackSize <= 0) { -	STACK_DEBUG(("skipping stack checks with success\n")); -	return TCL_CONTINUE; -    } - -    /* -     * Calculate a stack size with a safety margin. -     */ - -    *stackSizePtr = (rawStackSize / TCL_MAGIC_STACK_DIVISOR) -	    - (getpagesize() * TCL_RESERVED_STACK_PAGES); - -    return TCL_OK; -} -#endif /* TCL_NO_STACK_CHECK */  /*   *---------------------------------------------------------------------- | 
