1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Fixed GC race condition starting an autodelete thread

This commit is contained in:
Brian Fiete 2020-08-31 11:29:11 -07:00
parent 43660fb633
commit b3354ee635
5 changed files with 39 additions and 7 deletions

View file

@ -131,6 +131,8 @@ namespace System
public extern static void SetCollectFreeThreshold(int freeBytes); // -1 to disable, 0 to trigger collection after every single free. Defaults to 64MB public extern static void SetCollectFreeThreshold(int freeBytes); // -1 to disable, 0 to trigger collection after every single free. Defaults to 64MB
[CallingConvention(.Cdecl)] [CallingConvention(.Cdecl)]
public extern static void SetMaxPausePercentage(int maxPausePercentage); // 0 = disabled. Defaults to 20. public extern static void SetMaxPausePercentage(int maxPausePercentage); // 0 = disabled. Defaults to 20.
[CallingConvention(.Cdecl)]
extern static void AddPendingThread(void* internalThread);
#else #else
public static void Collect(bool async = true) {} public static void Collect(bool async = true) {}
private static void MarkAllStaticMembers() {} private static void MarkAllStaticMembers() {}
@ -141,6 +143,7 @@ namespace System
public static void SetAutoCollectPeriod(int periodMS) {} public static void SetAutoCollectPeriod(int periodMS) {}
public static void SetCollectFreeThreshold(int freeBytes) {} public static void SetCollectFreeThreshold(int freeBytes) {}
public static void SetMaxPausePercentage(int maxPausePercentage) {} public static void SetMaxPausePercentage(int maxPausePercentage) {}
extern static void AddPendingThread(void* internalThreadInfo) {}
#endif #endif
static void MarkDerefedObject(Object* obj) static void MarkDerefedObject(Object* obj)

View file

@ -41,6 +41,8 @@ namespace System.Threading
static void Thread_SetInternalThread(Object thread, void* internalThread) static void Thread_SetInternalThread(Object thread, void* internalThread)
{ {
if (internalThread != null)
GC.[Friend]AddPendingThread(internalThread);
((Thread)thread).[Friend]mInternalThread = (int)internalThread; ((Thread)thread).[Friend]mInternalThread = (int)internalThread;
} }

View file

@ -1390,6 +1390,16 @@ bool BFGC::ScanThreads()
{ {
ThreadInfo* thread = NULL; ThreadInfo* thread = NULL;
///
{
AutoCrit autoCrit(mCritSect);
for (auto& kv : mPendingThreads)
{
MarkFromGCThread(kv.mValue->mThread);
}
}
///
{ {
AutoCrit autoCrit(mCritSect); AutoCrit autoCrit(mCritSect);
if (threadIdx >= mThreadList.size()) if (threadIdx >= mThreadList.size())
@ -1938,6 +1948,7 @@ void BFGC::ThreadStarted()
thread->CalcStackStart(); thread->CalcStackStart();
mThreadList.Add(thread); mThreadList.Add(thread);
mPendingThreads.Remove(thread->mThreadId);
ThreadInfo::sCurThreadInfo = thread; ThreadInfo::sCurThreadInfo = thread;
} }
@ -2028,6 +2039,14 @@ void BFGC::RemoveStackMarkableObject(bf::System::Object* obj)
threadInfo->mStackMarkableObjects.RemoveAtFast(stackIdx); threadInfo->mStackMarkableObjects.RemoveAtFast(stackIdx);
} }
void BFGC::AddPendingThread(BfInternalThread* internalThread)
{
if (internalThread->mThread == 0)
return;
Beefy::AutoCrit autoCrit(mCritSect);
mPendingThreads.TryAdd(internalThread->mThreadId, internalThread);
}
void BFGC::Shutdown() void BFGC::Shutdown()
{ {
if (mShutdown) if (mShutdown)
@ -2710,6 +2729,11 @@ void GC::AddStackMarkableObject(Object* obj)
gBFGC.AddStackMarkableObject(obj); gBFGC.AddStackMarkableObject(obj);
} }
void GC::AddPendingThread(void* internalThreadInfo)
{
gBFGC.AddPendingThread((BfInternalThread*)internalThreadInfo);
}
void GC::RemoveStackMarkableObject(Object* obj) void GC::RemoveStackMarkableObject(Object* obj)
{ {
gBFGC.RemoveStackMarkableObject(obj); gBFGC.RemoveStackMarkableObject(obj);

View file

@ -324,6 +324,7 @@ public:
int mCurPendingGCSize; int mCurPendingGCSize;
int mMaxPendingGCSize; int mMaxPendingGCSize;
Beefy::Array<ThreadInfo*> mThreadList; Beefy::Array<ThreadInfo*> mThreadList;
Beefy::Dictionary<BfpThreadId, BfInternalThread*> mPendingThreads;
int mCurMutatorMarkCount; int mCurMutatorMarkCount;
int mCurGCMarkCount; int mCurGCMarkCount;
int mCurGCObjectQueuedCount; int mCurGCObjectQueuedCount;
@ -390,6 +391,7 @@ public:
void StopCollecting(); void StopCollecting();
void AddStackMarkableObject(bf::System::Object* obj); void AddStackMarkableObject(bf::System::Object* obj);
void RemoveStackMarkableObject(bf::System::Object* obj); void RemoveStackMarkableObject(bf::System::Object* obj);
void AddPendingThread(BfInternalThread* internalThread);
void Shutdown(); void Shutdown();
void InitDebugDump(); void InitDebugDump();
void EndDebugDump(); void EndDebugDump();
@ -463,6 +465,7 @@ namespace bf
BFRT_EXPORT static void StopCollecting(); BFRT_EXPORT static void StopCollecting();
BFRT_EXPORT static void AddStackMarkableObject(Object* obj); BFRT_EXPORT static void AddStackMarkableObject(Object* obj);
BFRT_EXPORT static void RemoveStackMarkableObject(Object* obj); BFRT_EXPORT static void RemoveStackMarkableObject(Object* obj);
BFRT_EXPORT static void AddPendingThread(void* internalThreadInfo);
public: public:
BFRT_EXPORT static void Shutdown(); BFRT_EXPORT static void Shutdown();

View file

@ -191,10 +191,10 @@ void Thread::StartInternal()
BfpSystem_InterlockedExchangeAdd32((uint32*)&gLiveThreadCount, 1); BfpSystem_InterlockedExchangeAdd32((uint32*)&gLiveThreadCount, 1);
BfInternalThread* internalThread = SetupInternalThread(); BfInternalThread* internalThread = SetupInternalThread();
SetInternalThread(internalThread);
internalThread->mThread = this; internalThread->mThread = this;
internalThread->mThreadHandle = BfpThread_Create(CStartProc, (void*)this, GetMaxStackSize(), BfpThreadCreateFlag_StackSizeReserve, &internalThread->mThreadId); internalThread->mThreadHandle = BfpThread_Create(CStartProc, (void*)this, GetMaxStackSize(), (BfpThreadCreateFlags)(BfpThreadCreateFlag_StackSizeReserve | BfpThreadCreateFlag_Suspended), &internalThread->mThreadId);
SetInternalThread(internalThread);
BfpThread_Resume(internalThread->mThreadHandle, NULL);
} }
int Thread::GetThreadId() int Thread::GetThreadId()