Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/coreclr/nativeaot/Runtime/RhConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,27 @@ bool RhConfig::ReadConfigValue(_In_z_ const char *name, uint64_t* pValue, bool d
return false;
}

bool RhConfig::ReadConfigValue(_In_z_ const char* envName, _In_z_ const char* configName, uint64_t* pValue, bool decimal)
{
uint64_t uiValue;
if (g_pRhConfig->ReadConfigValue(envName, &uiValue))
{
*pValue = uiValue;
return true;
}

if (configName)
{
if (g_pRhConfig->ReadKnobUInt64Value(configName, &uiValue))
{
*pValue = uiValue;
return true;
}
}

return false;
}

bool RhConfig::ReadKnobUInt64Value(_In_z_ const char *name, uint64_t* pValue)
{
const char *embeddedValue = nullptr;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/nativeaot/Runtime/RhConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class RhConfig
};

bool ReadConfigValue(_In_z_ const char* wszName, uint64_t* pValue, bool decimal = false);
bool ReadConfigValue(_In_z_ const char* wszEnvName, _In_z_ const char* wszConfigName, uint64_t* pValue, bool decimal = false);
bool ReadKnobUInt64Value(_In_z_ const char* wszName, uint64_t* pValue);
bool ReadKnobBooleanValue(_In_z_ const char* wszName, bool* pValue);

Expand Down
11 changes: 1 addition & 10 deletions src/coreclr/nativeaot/Runtime/gcenv.ee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -768,21 +768,12 @@ bool GCToEEInterface::GetIntConfigValue(const char* privateKey, const char* publ
}

uint64_t uiValue;
if (g_pRhConfig->ReadConfigValue(privateKey, &uiValue))
if (g_pRhConfig->ReadConfigValue(privateKey, publicKey, &uiValue))
{
*value = uiValue;
return true;
}

if (publicKey)
{
if (g_pRhConfig->ReadKnobUInt64Value(publicKey, &uiValue))
{
*value = uiValue;
return true;
}
}

return false;
}

Expand Down
14 changes: 14 additions & 0 deletions src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,20 @@ REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalStartBackgroundWork(_In_ BackgroundCall

int st = pthread_attr_init(&attrs);
ASSERT(st == 0);

// Keep the same arbitrary minimum and maximum from the coreclr\vm layer.
const size_t minStack = 0x10000; // 64K
const size_t maxStack = 0x80000000; // 2G

uint64_t stackSize;
if (g_pRhConfig->ReadConfigValue("Threading_DefaultStackSize", "System.Threading.DefaultStackSize", &stackSize))
{
if (stacksize < maxStack && stacksize >= minStack)
{
st = pthread_attr_setstacksize(&attrs, (size_t)stacksize);
ASSERT(st == 0);
}
}

static const int NormalPriority = 0;
static const int HighestPriority = -20;
Expand Down
17 changes: 16 additions & 1 deletion src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -893,9 +893,24 @@ static pfnSetThreadDescription g_pfnSetThreadDescription = SET_THREAD_DESCRIPTIO

REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalStartBackgroundWork(_In_ BackgroundCallback callback, _In_opt_ void* pCallbackContext, BOOL highPriority)
{
// Keep the same arbitrary minimum and maximum from the coreclr\vm layer.
const size_t minStack = 0x10000; // 64K
const size_t maxStack = 0x80000000; // 2G

uint64_t stacksize = 0;

uint64_t uiStacksize;
if (g_pRhConfig->ReadConfigValue("Threading_DefaultStackSize", "System.Threading.DefaultStackSize", &uiStacksize))
{
if (uiStacksize < maxStack || uiStacksize >= minStack)
{
stacksize = uiStacksize;
}
}

HANDLE hThread = CreateThread(
NULL,
0,
(DWORD)stacksize,
(LPTHREAD_START_ROUTINE)callback,
pCallbackContext,
highPriority ? CREATE_SUSPENDED : 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,14 @@ private unsafe bool CreateThread(GCHandle thisThreadHandle)
// This also avoids OOM after creating the thread.
_stopped = new ManualResetEvent(false);

if (!Interop.Sys.CreateThread((IntPtr)_startHelper!._maxStackSize, &ThreadEntryPoint, (IntPtr)thisThreadHandle))
int stackSize = _startHelper!._maxStackSize;

if (stackSize <= 0)
{
stackSize = GetDefaultStackSize();
}

if (!Interop.Sys.CreateThread((IntPtr)stackSize, &ThreadEntryPoint, (IntPtr)thisThreadHandle))
{
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,13 @@ private bool JoinInternal(int millisecondsTimeout)
private unsafe bool CreateThread(GCHandle thisThreadHandle)
{
const int AllocationGranularity = 0x10000; // 64 KiB

int stackSize = _startHelper._maxStackSize;

if (stackSize <= 0)
{
stackSize = GetDefaultStackSize();
}

if ((0 < stackSize) && (stackSize < AllocationGranularity))
{
// If StackSizeParamIsAReservation flag is set and the reserve size specified by CreateThread's
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,27 @@ private static void StopThread(Thread thread)
}
}

internal static int GetDefaultStackSize()
{
// Keep the same arbitrary minimum and maximum from the coreclr\vm layer.
// The max was 0x80000000 (2G).
// This is checked by the value being parsed into an int32.
const uint minStack = 0x10000; // 64K

int sizeFromConfig = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig(
"System.Threading.DefaultStackSize",
"Threading_DefaultStackSize",
0,
false);

if (sizeFromConfig >= minStack)
{
return sizeFromConfig;
}

return 0;
}

internal static void IncrementRunningForeground()
{
Interlocked.Increment(ref s_foregroundRunningCount);
Expand Down
Loading