diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2017-02-10 20:35:12 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2017-02-10 20:35:12 +0900 |
commit | 4b11dc566a5bbfa1378d6266525c281b028abcc8 (patch) | |
tree | b48831a898906734f8884d08b6e18f1144ee2b82 /src/pal/src/thread/thread.cpp | |
parent | db20f3f1bb8595633a7e16c8900fd401a453a6b5 (diff) | |
download | coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.tar.gz coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.tar.bz2 coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.zip |
Imported Upstream version 1.0.0.9910upstream/1.0.0.9910
Diffstat (limited to 'src/pal/src/thread/thread.cpp')
-rw-r--r-- | src/pal/src/thread/thread.cpp | 108 |
1 files changed, 40 insertions, 68 deletions
diff --git a/src/pal/src/thread/thread.cpp b/src/pal/src/thread/thread.cpp index 566ef855b4..53283320c5 100644 --- a/src/pal/src/thread/thread.cpp +++ b/src/pal/src/thread/thread.cpp @@ -34,6 +34,8 @@ SET_DEFAULT_DEBUG_CHANNEL(THREAD); // some headers have code with asserts, so do #include "pal/module.h" #include "pal/environ.h" #include "pal/init.h" +#include "pal/utils.h" +#include "pal/virtual.h" #if defined(__NetBSD__) && !HAVE_PTHREAD_GETCPUCLOCKID #include <sys/cdefs.h> @@ -77,13 +79,6 @@ using namespace CorUnix; /* ------------------- Definitions ------------------------------*/ -// The default stack size of a newly created thread (currently 256KB) -// when the dwStackSize parameter of PAL_CreateThread() -// is zero. This value can be set by setting the -// environment variable PAL_THREAD_DEFAULT_STACK_SIZE -// (the value should be in bytes and in hex). -DWORD CPalThread::s_dwDefaultThreadStackSize = 256*1024; - /* list of free CPalThread objects */ static Volatile<CPalThread*> free_threads_list = NULL; @@ -528,6 +523,7 @@ CorUnix::InternalCreateThread( #endif // PTHREAD_CREATE_MODIFIES_ERRNO BOOL fHoldingProcessLock = FALSE; int iError = 0; + size_t alignedStackSize; if (0 != terminator) { @@ -573,7 +569,24 @@ CorUnix::InternalCreateThread( palError = ERROR_INVALID_PARAMETER; goto EXIT; } - + + alignedStackSize = dwStackSize; + if (alignedStackSize != 0) + { + // Some systems require the stack size to be aligned to the page size + if (sizeof(alignedStackSize) <= sizeof(dwStackSize) && alignedStackSize + (VIRTUAL_PAGE_SIZE - 1) < alignedStackSize) + { + // When coming here from the public API surface, the incoming value is originally a nonnegative signed int32, so + // this shouldn't happen + ASSERT( + "Couldn't align the requested stack size (%Iu) to the page size because the stack size was too large\n", + alignedStackSize); + palError = ERROR_INVALID_PARAMETER; + goto EXIT; + } + alignedStackSize = ALIGN_UP(alignedStackSize, VIRTUAL_PAGE_SIZE); + } + // Ignore the STACK_SIZE_PARAM_IS_A_RESERVATION flag dwCreationFlags &= ~STACK_SIZE_PARAM_IS_A_RESERVATION; @@ -616,42 +629,34 @@ CorUnix::InternalCreateThread( fAttributesInitialized = TRUE; /* adjust the stack size if necessary */ - if (0 != pthread_attr_getstacksize(&pthreadAttr, &pthreadStackSize)) + if (alignedStackSize != 0) { - ERROR("couldn't set thread stack size\n"); - palError = ERROR_INTERNAL_ERROR; - goto EXIT; - } - - TRACE("default pthread stack size is %d, caller requested %d (default is %d)\n", - pthreadStackSize, dwStackSize, CPalThread::s_dwDefaultThreadStackSize); - - if (0 == dwStackSize) - { - dwStackSize = CPalThread::s_dwDefaultThreadStackSize; - } - #ifdef PTHREAD_STACK_MIN - if (PTHREAD_STACK_MIN > pthreadStackSize) - { - WARN("default stack size is reported as %d, but PTHREAD_STACK_MIN is " - "%d\n", pthreadStackSize, PTHREAD_STACK_MIN); - } -#endif - - if (pthreadStackSize < dwStackSize) - { - TRACE("setting thread stack size to %d\n", dwStackSize); - if (0 != pthread_attr_setstacksize(&pthreadAttr, dwStackSize)) + const size_t MinStackSize = PTHREAD_STACK_MIN; +#else // !PTHREAD_STACK_MIN + const size_t MinStackSize = 64 * 1024; // this value is typically accepted by pthread_attr_setstacksize() +#endif // PTHREAD_STACK_MIN + _ASSERTE(IS_ALIGNED(MinStackSize, VIRTUAL_PAGE_SIZE)); + if (alignedStackSize < MinStackSize) { - ERROR("couldn't set pthread stack size to %d\n", dwStackSize); + // Adjust the stack size to a minimum value that is likely to be accepted by pthread_attr_setstacksize(). If this + // function fails, typically the caller will end up throwing OutOfMemoryException under the assumption that the + // requested stack size is too large or the system does not have sufficient memory to create a thread. Try to + // prevent failing just just because the stack size value is too low. + alignedStackSize = MinStackSize; + } + + TRACE("setting thread stack size to %Iu\n", alignedStackSize); + if (0 != pthread_attr_setstacksize(&pthreadAttr, alignedStackSize)) + { + ERROR("couldn't set pthread stack size to %Iu\n", alignedStackSize); palError = ERROR_INTERNAL_ERROR; goto EXIT; } } else { - TRACE("using the system default thread stack size of %d\n", pthreadStackSize); + TRACE("using the system default thread stack size\n"); } #if HAVE_THREAD_SELF || HAVE__LWP_SELF @@ -1755,39 +1760,6 @@ fail: return NULL; } - -#define PAL_THREAD_DEFAULT_STACK_SIZE "PAL_THREAD_DEFAULT_STACK_SIZE" - -PAL_ERROR -CorUnix::InitializeGlobalThreadData( - void - ) -{ - PAL_ERROR palError = NO_ERROR; - char *pszStackSize = NULL; - - // - // Read in the environment to see whether we need to change the default - // thread stack size. - // - pszStackSize = EnvironGetenv(PAL_THREAD_DEFAULT_STACK_SIZE); - if (NULL != pszStackSize) - { - // Environment variable exists - char *pszEnd; - DWORD dw = PAL_strtoul(pszStackSize, &pszEnd, 16); // treat it as hex - if ( (pszStackSize != pszEnd) && (0 != dw) ) - { - CPalThread::s_dwDefaultThreadStackSize = dw; - } - - free(pszStackSize); - } - - return palError; -} - - /*++ Function: CreateThreadData |