mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Allows for stack base to change
This commit is contained in:
parent
2510c16389
commit
4472449cc4
6 changed files with 135 additions and 66 deletions
|
@ -214,6 +214,8 @@ BFGC::ThreadInfo::~ThreadInfo()
|
||||||
{
|
{
|
||||||
if (mThreadHandle != NULL)
|
if (mThreadHandle != NULL)
|
||||||
BfpThread_Release(mThreadHandle);
|
BfpThread_Release(mThreadHandle);
|
||||||
|
if (mThreadInfo != NULL)
|
||||||
|
BfpThreadInfo_Release(mThreadInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BFGC::ThreadInfo::WantsSuspend()
|
bool BFGC::ThreadInfo::WantsSuspend()
|
||||||
|
@ -226,6 +228,14 @@ bool BFGC::ThreadInfo::WantsSuspend()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BFGC::ThreadInfo::CalcStackStart()
|
||||||
|
{
|
||||||
|
intptr stackBase;
|
||||||
|
int stackLimit;
|
||||||
|
BfpThreadInfo_GetStackInfo(mThreadInfo, &stackBase, &stackLimit, BfpThreadInfoFlags_NoCache, NULL);
|
||||||
|
mStackStart = stackBase;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef BF_GC_LOG_ENABLED
|
#ifdef BF_GC_LOG_ENABLED
|
||||||
|
@ -1447,6 +1457,7 @@ bool BFGC::ScanThreads()
|
||||||
|
|
||||||
mQueueMarkObjects = true;
|
mQueueMarkObjects = true;
|
||||||
ConservativeScan(regVals, regValCount * sizeof(intptr));
|
ConservativeScan(regVals, regValCount * sizeof(intptr));
|
||||||
|
thread->CalcStackStart();
|
||||||
int length = thread->mStackStart - stackPtr;
|
int length = thread->mStackStart - stackPtr;
|
||||||
|
|
||||||
AdjustStackPtr(stackPtr, length);
|
AdjustStackPtr(stackPtr, length);
|
||||||
|
@ -1895,11 +1906,9 @@ void BFGC::ThreadStarted()
|
||||||
thread->mThreadHandle = BfpThread_GetCurrent();
|
thread->mThreadHandle = BfpThread_GetCurrent();
|
||||||
thread->mThreadId = BfpThread_GetCurrentId();
|
thread->mThreadId = BfpThread_GetCurrentId();
|
||||||
thread->mTEB = GetTEB((HANDLE)thread->mThreadHandle);
|
thread->mTEB = GetTEB((HANDLE)thread->mThreadHandle);
|
||||||
|
thread->mThreadInfo = BfpThreadInfo_Create();
|
||||||
intptr stackBase;
|
|
||||||
int stackLimit;
|
thread->CalcStackStart();
|
||||||
BfpThread_GetStackInfo(thread->mThreadHandle, &stackBase, &stackLimit, NULL);
|
|
||||||
thread->mStackStart = stackBase;
|
|
||||||
|
|
||||||
mThreadList.Add(thread);
|
mThreadList.Add(thread);
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,7 @@ public:
|
||||||
|
|
||||||
Beefy::CritSect mCritSect;
|
Beefy::CritSect mCritSect;
|
||||||
BfpThread* mThreadHandle;
|
BfpThread* mThreadHandle;
|
||||||
|
BfpThreadInfo* mThreadInfo;
|
||||||
BfpThreadId mThreadId;
|
BfpThreadId mThreadId;
|
||||||
void* mTEB;
|
void* mTEB;
|
||||||
intptr mStackStart;
|
intptr mStackStart;
|
||||||
|
@ -180,6 +181,7 @@ public:
|
||||||
{
|
{
|
||||||
mThreadId = 0;
|
mThreadId = 0;
|
||||||
mThreadHandle = NULL;
|
mThreadHandle = NULL;
|
||||||
|
mThreadInfo = NULL;
|
||||||
mTEB = NULL;
|
mTEB = NULL;
|
||||||
mStackStart = NULL;
|
mStackStart = NULL;
|
||||||
mRunning = true;
|
mRunning = true;
|
||||||
|
@ -188,6 +190,7 @@ public:
|
||||||
~ThreadInfo();
|
~ThreadInfo();
|
||||||
|
|
||||||
bool WantsSuspend();
|
bool WantsSuspend();
|
||||||
|
void CalcStackStart();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RawLeakInfo
|
struct RawLeakInfo
|
||||||
|
|
|
@ -24,6 +24,7 @@ typedef uint64 BfpTimeStamp;
|
||||||
|
|
||||||
typedef intptr BfpThreadId;
|
typedef intptr BfpThreadId;
|
||||||
struct BfpThread;
|
struct BfpThread;
|
||||||
|
struct BfpThreadInfo;
|
||||||
struct BfpFile;
|
struct BfpFile;
|
||||||
struct BfpSpawn;
|
struct BfpSpawn;
|
||||||
struct BfpFileWatcher;
|
struct BfpFileWatcher;
|
||||||
|
@ -231,6 +232,12 @@ enum BfpThreadPriority
|
||||||
BfpThreadPriority_VeryHigh =2
|
BfpThreadPriority_VeryHigh =2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BfpThreadInfoFlags
|
||||||
|
{
|
||||||
|
BfpThreadInfoFlags_None = 0,
|
||||||
|
BfpThreadInfoFlags_NoCache = 1
|
||||||
|
};
|
||||||
|
|
||||||
enum BfpThreadResult
|
enum BfpThreadResult
|
||||||
{
|
{
|
||||||
BfpThreadResult_Ok = BfpResult_Ok,
|
BfpThreadResult_Ok = BfpResult_Ok,
|
||||||
|
@ -251,10 +258,13 @@ BFP_EXPORT void BFP_CALLTYPE BfpThread_SetPriority(BfpThread* thread, BfpThreadP
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_Suspend(BfpThread* thread, BfpThreadResult* outResult);
|
BFP_EXPORT void BFP_CALLTYPE BfpThread_Suspend(BfpThread* thread, BfpThreadResult* outResult);
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_Resume(BfpThread* thread, BfpThreadResult* outResult);
|
BFP_EXPORT void BFP_CALLTYPE BfpThread_Resume(BfpThread* thread, BfpThreadResult* outResult);
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_GetIntRegisters(BfpThread* thread, intptr* outStackPtr, intptr* outIntRegs, int* inOutIntRegCount, BfpThreadResult* outResult);
|
BFP_EXPORT void BFP_CALLTYPE BfpThread_GetIntRegisters(BfpThread* thread, intptr* outStackPtr, intptr* outIntRegs, int* inOutIntRegCount, BfpThreadResult* outResult);
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_GetStackInfo(BfpThread* thread, intptr* outStackBase, int* outStackLimit, BfpThreadResult* outResult);
|
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_Sleep(int sleepMS);
|
BFP_EXPORT void BFP_CALLTYPE BfpThread_Sleep(int sleepMS);
|
||||||
BFP_EXPORT bool BFP_CALLTYPE BfpThread_Yield();
|
BFP_EXPORT bool BFP_CALLTYPE BfpThread_Yield();
|
||||||
|
|
||||||
|
BFP_EXPORT BfpThreadInfo* BFP_CALLTYPE BfpThreadInfo_Create();
|
||||||
|
BFP_EXPORT void BFP_CALLTYPE BfpThreadInfo_Release(BfpThreadInfo* threadInfo);
|
||||||
|
BFP_EXPORT void BFP_CALLTYPE BfpThreadInfo_GetStackInfo(BfpThreadInfo* thread, intptr* outStackBase, int* outStackLimit, BfpThreadInfoFlags flags, BfpThreadResult* outResult);
|
||||||
|
|
||||||
struct BfpCritSect;
|
struct BfpCritSect;
|
||||||
BFP_EXPORT BfpCritSect* BFP_CALLTYPE BfpCritSect_Create();
|
BFP_EXPORT BfpCritSect* BFP_CALLTYPE BfpCritSect_Create();
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Release(BfpCritSect* critSect);
|
BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Release(BfpCritSect* critSect);
|
||||||
|
|
|
@ -1166,6 +1166,7 @@ struct BfpThreadInfo
|
||||||
{
|
{
|
||||||
intptr mStackBase;
|
intptr mStackBase;
|
||||||
int mStackLimit;
|
int mStackLimit;
|
||||||
|
pthread_t mPThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
static __thread BfpThread* gCurrentThread;
|
static __thread BfpThread* gCurrentThread;
|
||||||
|
@ -1338,32 +1339,6 @@ BFP_EXPORT void BFP_CALLTYPE BfpThread_GetIntRegisters(BfpThread* thread, intptr
|
||||||
NOT_IMPL;
|
NOT_IMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_GetStackInfo(BfpThread* thread, intptr* outStackBase, int* outStackLimit, BfpThreadResult* outResult)
|
|
||||||
{
|
|
||||||
#ifdef BFP_HAS_PTHREAD_GETATTR_NP
|
|
||||||
if (gCurrentThreadInfo.mStackBase == 0)
|
|
||||||
{
|
|
||||||
void* stackBase = 0;
|
|
||||||
size_t stackLimit = 0;
|
|
||||||
|
|
||||||
pthread_attr_t attr;
|
|
||||||
pthread_getattr_np(pthread_self(), &attr);
|
|
||||||
pthread_attr_getstack(&attr, &stackBase, &stackLimit);
|
|
||||||
|
|
||||||
gCurrentThreadInfo.mStackBase = (intptr)stackBase + stackLimit;
|
|
||||||
gCurrentThreadInfo.mStackLimit = (int)stackLimit;
|
|
||||||
pthread_attr_destroy(&attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
*outStackBase = gCurrentThreadInfo.mStackBase;
|
|
||||||
*outStackLimit = gCurrentThreadInfo.mStackLimit;
|
|
||||||
|
|
||||||
OUTRESULT(BfpThreadResult_Ok);
|
|
||||||
#else
|
|
||||||
OUTRESULT(BfpThreadResult_UnknownError);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_Sleep(int sleepMS)
|
BFP_EXPORT void BFP_CALLTYPE BfpThread_Sleep(int sleepMS)
|
||||||
{
|
{
|
||||||
usleep(sleepMS * 1000);
|
usleep(sleepMS * 1000);
|
||||||
|
@ -1374,6 +1349,55 @@ BFP_EXPORT bool BFP_CALLTYPE BfpThread_Yield()
|
||||||
return sched_yield() == 0;
|
return sched_yield() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
BFP_EXPORT BfpThreadInfo* BFP_CALLTYPE BfpThreadInfo_Create()
|
||||||
|
{
|
||||||
|
BfpThreadInfo* threadInfo = new BfpThreadInfo();
|
||||||
|
threadInfo->mStackBase = 0;
|
||||||
|
threadInfo->mStackLimit = 0;
|
||||||
|
threadInfo->mPThread = pthread_self();
|
||||||
|
}
|
||||||
|
|
||||||
|
BFP_EXPORT void BFP_CALLTYPE BfpThreadInfo_Release(BfpThreadInfo* threadInfo)
|
||||||
|
{
|
||||||
|
delete threadInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFP_EXPORT void BFP_CALLTYPE BfpThreadInfo_GetStackInfo(BfpThreadInfo* threadInfo, intptr* outStackBase, int* outStackLimit, BfpThreadResult* outResult)
|
||||||
|
{
|
||||||
|
#ifdef BFP_HAS_PTHREAD_GETATTR_NP
|
||||||
|
if (threadInfo == NULL)
|
||||||
|
{
|
||||||
|
threadInfo = &gCurrentThreadInfo;
|
||||||
|
threadInfo->mPThread = pthread_self();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threadInfo->mStackBase == 0)
|
||||||
|
{
|
||||||
|
void* stackBase = 0;
|
||||||
|
size_t stackLimit = 0;
|
||||||
|
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_getattr_np(threadInfo->mPThread, &attr);
|
||||||
|
pthread_attr_getstack(&attr, &stackBase, &stackLimit);
|
||||||
|
|
||||||
|
threadInfo->mStackBase = (intptr)stackBase + stackLimit;
|
||||||
|
threadInfo->mStackLimit = (int)stackLimit;
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
*outStackBase = threadInfo->mStackBase;
|
||||||
|
*outStackLimit = threadInfo->mStackLimit;
|
||||||
|
|
||||||
|
OUTRESULT(BfpThreadResult_Ok);
|
||||||
|
#else
|
||||||
|
OUTRESULT(BfpThreadResult_UnknownError);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
struct BfpCritSect
|
struct BfpCritSect
|
||||||
{
|
{
|
||||||
pthread_mutex_t mPMutex;
|
pthread_mutex_t mPMutex;
|
||||||
|
|
|
@ -2253,39 +2253,6 @@ BFP_EXPORT void BFP_CALLTYPE BfpThread_GetIntRegisters(BfpThread* thread, intptr
|
||||||
*inOutIntRegCount = (int)(curPtr - outIntRegs);
|
*inOutIntRegCount = (int)(curPtr - outIntRegs);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BfpThreadStackInfo
|
|
||||||
{
|
|
||||||
intptr mStackBase;
|
|
||||||
intptr mStackLimit;
|
|
||||||
};
|
|
||||||
static __declspec(thread) BfpThreadStackInfo gThreadStackInfo;
|
|
||||||
|
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_GetStackInfo(BfpThread* thread, intptr* outStackBase, int* outStackLimit, BfpThreadResult* outResult)
|
|
||||||
{
|
|
||||||
if (gThreadStackInfo.mStackBase == 0)
|
|
||||||
{
|
|
||||||
auto teb = (NT_TIB*)NtCurrentTeb();
|
|
||||||
|
|
||||||
MEMORY_BASIC_INFORMATION stackInfo = { 0 };
|
|
||||||
// We subtract one page for our request. VirtualQuery rounds UP to the next page.
|
|
||||||
// Unfortunately, the stack grows down. If we're on the first page (last page in the
|
|
||||||
// VirtualAlloc), we'll be moved to the next page, which is off the stack! Note this
|
|
||||||
// doesn't work right for IA64 due to bigger pages.
|
|
||||||
void* currentAddr = (void*)((intptr_t)&stackInfo - 4096);
|
|
||||||
|
|
||||||
// Query for the current stack allocation information.
|
|
||||||
VirtualQuery(currentAddr, &stackInfo, sizeof(MEMORY_BASIC_INFORMATION));
|
|
||||||
|
|
||||||
gThreadStackInfo.mStackBase = (uintptr_t)teb->StackBase;
|
|
||||||
gThreadStackInfo.mStackLimit = (uintptr_t)stackInfo.AllocationBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
*outStackBase = (intptr)gThreadStackInfo.mStackBase;
|
|
||||||
*outStackLimit = (int)(gThreadStackInfo.mStackBase - gThreadStackInfo.mStackLimit);
|
|
||||||
OUTRESULT(BfpThreadResult_Ok);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BfpCritSect
|
struct BfpCritSect
|
||||||
{
|
{
|
||||||
CRITICAL_SECTION mCritSect;
|
CRITICAL_SECTION mCritSect;
|
||||||
|
@ -2303,6 +2270,62 @@ BFP_EXPORT bool BFP_CALLTYPE BfpThread_Yield()
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
|
struct BfpThreadInfo
|
||||||
|
{
|
||||||
|
intptr mStackBase;
|
||||||
|
intptr mStackLimit;
|
||||||
|
NT_TIB* mTeb;
|
||||||
|
};
|
||||||
|
|
||||||
|
BFP_EXPORT BfpThreadInfo* BFP_CALLTYPE BfpThreadInfo_Create()
|
||||||
|
{
|
||||||
|
BfpThreadInfo* threadInfo = new BfpThreadInfo();
|
||||||
|
threadInfo->mStackBase = 0;
|
||||||
|
threadInfo->mStackLimit = 0;
|
||||||
|
threadInfo->mTeb = (NT_TIB*)NtCurrentTeb();
|
||||||
|
return threadInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFP_EXPORT void BFP_CALLTYPE BfpThreadInfo_Release(BfpThreadInfo* threadInfo)
|
||||||
|
{
|
||||||
|
delete threadInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __declspec(thread) BfpThreadInfo gThreadStackInfo;
|
||||||
|
|
||||||
|
BFP_EXPORT void BFP_CALLTYPE BfpThreadInfo_GetStackInfo(BfpThreadInfo* threadInfo, intptr* outStackBase, int* outStackLimit, BfpThreadInfoFlags flags, BfpThreadResult* outResult)
|
||||||
|
{
|
||||||
|
if (threadInfo == NULL)
|
||||||
|
{
|
||||||
|
threadInfo = &gThreadStackInfo;
|
||||||
|
if (threadInfo->mTeb == NULL)
|
||||||
|
threadInfo->mTeb = (NT_TIB*)NtCurrentTeb();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((threadInfo->mStackBase == 0) || ((flags & BfpThreadInfoFlags_NoCache) != 0))
|
||||||
|
{
|
||||||
|
MEMORY_BASIC_INFORMATION stackInfo = { 0 };
|
||||||
|
// We subtract one page for our request. VirtualQuery rounds UP to the next page.
|
||||||
|
// Unfortunately, the stack grows down. If we're on the first page (last page in the
|
||||||
|
// VirtualAlloc), we'll be moved to the next page, which is off the stack! Note this
|
||||||
|
// doesn't work right for IA64 due to bigger pages.
|
||||||
|
void* currentAddr = (void*)((intptr_t)&stackInfo - 4096);
|
||||||
|
|
||||||
|
// Query for the current stack allocation information.
|
||||||
|
VirtualQuery(currentAddr, &stackInfo, sizeof(MEMORY_BASIC_INFORMATION));
|
||||||
|
|
||||||
|
threadInfo->mStackBase = (uintptr_t)threadInfo->mTeb->StackBase;
|
||||||
|
threadInfo->mStackLimit = (uintptr_t)stackInfo.AllocationBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
*outStackBase = (intptr)threadInfo->mStackBase;
|
||||||
|
*outStackLimit = (int)(threadInfo->mStackBase - threadInfo->mStackLimit);
|
||||||
|
OUTRESULT(BfpThreadResult_Ok);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
BFP_EXPORT BfpCritSect* BFP_CALLTYPE BfpCritSect_Create()
|
BFP_EXPORT BfpCritSect* BFP_CALLTYPE BfpCritSect_Create()
|
||||||
{
|
{
|
||||||
BfpCritSect* critSect = new BfpCritSect();
|
BfpCritSect* critSect = new BfpCritSect();
|
||||||
|
|
|
@ -25,7 +25,7 @@ bool StackHelper::CanStackExpand(int wantBytes)
|
||||||
intptr stackBase = 0;
|
intptr stackBase = 0;
|
||||||
int stackLimit = 0;
|
int stackLimit = 0;
|
||||||
BfpThreadResult threadResult;
|
BfpThreadResult threadResult;
|
||||||
BfpThread_GetStackInfo(NULL, &stackBase, &stackLimit, &threadResult);
|
BfpThreadInfo_GetStackInfo(NULL, &stackBase, &stackLimit, BfpThreadInfoFlags_None, &threadResult);
|
||||||
if (threadResult != BfpThreadResult_Ok)
|
if (threadResult != BfpThreadResult_Ok)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue