浏览代码

Implemented IsBackground. Added GC.Disable

Brian Fiete 7 月之前
父节点
当前提交
c21be1eea1
共有 6 个文件被更改,包括 69 次插入24 次删除
  1. 3 0
      BeefLibs/corlib/src/GC.bf
  2. 30 19
      BeefLibs/corlib/src/Threading/Thread.bf
  3. 11 0
      BeefRT/dbg/gc.cpp
  4. 3 1
      BeefRT/dbg/gc.h
  5. 20 4
      BeefRT/rt/Thread.cpp
  6. 2 0
      BeefRT/rt/Thread.h

+ 3 - 0
BeefLibs/corlib/src/GC.bf

@@ -108,6 +108,8 @@ namespace System
 		[CallingConvention(.Cdecl)]
 		[CallingConvention(.Cdecl)]
 		private extern static void Init();
 		private extern static void Init();
 		[CallingConvention(.Cdecl)]
 		[CallingConvention(.Cdecl)]
+		public extern static void Disable();
+		[CallingConvention(.Cdecl)]
         public extern static void Collect(bool async = true);
         public extern static void Collect(bool async = true);
 		[CallingConvention(.Cdecl)]
 		[CallingConvention(.Cdecl)]
 		private extern static void StopCollecting();
 		private extern static void StopCollecting();
@@ -136,6 +138,7 @@ namespace System
 		[CallingConvention(.Cdecl)]
 		[CallingConvention(.Cdecl)]
 		public extern static void ExcludeThreadId(int thereadId);
 		public extern static void ExcludeThreadId(int thereadId);
 #else
 #else
+		public static void Disable() {}
 		public static void Collect(bool async = true) {}
 		public static void Collect(bool async = true) {}
 		private static void MarkAllStaticMembers() {}
 		private static void MarkAllStaticMembers() {}
 		public static void DebugDumpLeaks() {}
 		public static void DebugDumpLeaks() {}

+ 30 - 19
BeefLibs/corlib/src/Threading/Thread.bf

@@ -21,8 +21,9 @@ namespace System.Threading
 
 
         bool mAutoDelete = true;
         bool mAutoDelete = true;
 		bool mJoinOnDelete;
 		bool mJoinOnDelete;
+		bool mIsBackground;
 
 
-		static Monitor sMonitor = new .() ~ delete _;
+		static Monitor sMonitor = new .() ~ DeleteAndNullify!(_);
 		static Event<delegate void()> sOnExit ~ _.Dispose();
 		static Event<delegate void()> sOnExit ~ _.Dispose();
 		Event<delegate void()> mOnExit ~ _.Dispose();
 		Event<delegate void()> mOnExit ~ _.Dispose();
 
 
@@ -86,6 +87,8 @@ namespace System.Threading
 					thread.InformThreadNameChange(thread.mName);
 					thread.InformThreadNameChange(thread.mName);
 				if (thread.mPriority != .Normal)
 				if (thread.mPriority != .Normal)
 					thread.SetPriorityNative((.)thread.mPriority);
 					thread.SetPriorityNative((.)thread.mPriority);
+				if (thread.mIsBackground)
+					thread.SetBackgroundNative(thread.mIsBackground);
 
 
                 int32 stackStart = 0;
                 int32 stackStart = 0;
                 thread.SetStackStart((void*)&stackStart);
                 thread.SetStackStart((void*)&stackStart);
@@ -239,27 +242,27 @@ namespace System.Threading
 			}
 			}
 		}
 		}
 
 
-	public void Start()
-	{
-		StartInternal();
-	}
+		public void Start()
+		{
+			StartInternal();
+		}
 
 
         public void Start(bool autoDelete)
         public void Start(bool autoDelete)
         {
         {
             	mAutoDelete = autoDelete;
             	mAutoDelete = autoDelete;
             	Start();
             	Start();
         }
         }
-
-	public void Start(Object parameter)
-	{
-		if (mDelegate is ThreadStart)
+		
+		public void Start(Object parameter)
 		{
 		{
-			Runtime.FatalError();
+			if (mDelegate is ThreadStart)
+			{
+				Runtime.FatalError();
+			}
+			mThreadStartArg = parameter;
+			StartInternal();
 		}
 		}
-		mThreadStartArg = parameter;
-		StartInternal();
-	}
-        
+		    
         public void Start(Object parameter, bool autoDelete)
         public void Start(Object parameter, bool autoDelete)
         {
         {
             mAutoDelete = autoDelete;
             mAutoDelete = autoDelete;
@@ -384,10 +387,13 @@ namespace System.Threading
 
 
         public ~this()
         public ~this()
         {
         {
-			using (sMonitor.Enter())
+			if (sMonitor != null)
 			{
 			{
-				mOnExit();
-				sOnExit();
+				using (sMonitor.Enter())
+				{
+					mOnExit();
+					sOnExit();
+				}
 			}
 			}
 
 
 			if (mJoinOnDelete)
 			if (mJoinOnDelete)
@@ -403,8 +409,13 @@ namespace System.Threading
 
 
         public bool IsBackground
         public bool IsBackground
         {
         {
-            get { return IsBackgroundNative(); }
-            set { SetBackgroundNative(value); }
+            get { return mIsBackground; }
+            set
+			{
+				mIsBackground = value;
+				if (mInternalThread != 0)
+					SetBackgroundNative(mIsBackground);
+			}
         }
         }
 		
 		
 		public void SetJoinOnDelete(bool joinOnDelete)
 		public void SetJoinOnDelete(bool joinOnDelete)

+ 11 - 0
BeefRT/dbg/gc.cpp

@@ -2180,6 +2180,12 @@ void BFGC::AddPendingThread(BfInternalThread* internalThread)
 	mPendingThreads.TryAdd(internalThread->mThreadId, internalThread);
 	mPendingThreads.TryAdd(internalThread->mThreadId, internalThread);
 }
 }
 
 
+void BFGC::Disable()
+{
+	StopCollecting();
+	mGracelessShutdown = true;
+}
+
 void BFGC::Shutdown()
 void BFGC::Shutdown()
 {
 {
 	if (mShutdown)
 	if (mShutdown)
@@ -2896,6 +2902,11 @@ void GC::RemoveStackMarkableObject(Object* obj)
 	gBFGC.RemoveStackMarkableObject(obj);
 	gBFGC.RemoveStackMarkableObject(obj);
 }
 }
 
 
+void GC::Disable()
+{
+	gBFGC.Disable();
+}
+
 void GC::Shutdown()
 void GC::Shutdown()
 {
 {
 	gBFGC.Shutdown();
 	gBFGC.Shutdown();

+ 3 - 1
BeefRT/dbg/gc.h

@@ -397,6 +397,7 @@ public:
 	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 AddPendingThread(BfInternalThread* internalThread);
+	void Disable();
 	void Shutdown();	
 	void Shutdown();	
 	void InitDebugDump();
 	void InitDebugDump();
 	void EndDebugDump();	
 	void EndDebugDump();	
@@ -474,7 +475,8 @@ namespace bf
 			BFRT_EXPORT static void AddPendingThread(void* internalThreadInfo);			
 			BFRT_EXPORT static void AddPendingThread(void* internalThreadInfo);			
 			
 			
 		public:
 		public:
-			BFRT_EXPORT static void Shutdown();			
+			BFRT_EXPORT static void Disable();
+			BFRT_EXPORT static void Shutdown();
 			BFRT_EXPORT static void Collect(bool async);
 			BFRT_EXPORT static void Collect(bool async);
 			BFRT_EXPORT static void Report();
 			BFRT_EXPORT static void Report();
 			BFRT_EXPORT static void Mark(Object* obj);
 			BFRT_EXPORT static void Mark(Object* obj);

+ 20 - 4
BeefRT/rt/Thread.cpp

@@ -17,6 +17,7 @@ BF_TLS_DECLSPEC Thread* Thread::sCurrentThread;
 #endif
 #endif
 
 
 static volatile int gLiveThreadCount;
 static volatile int gLiveThreadCount;
+static volatile int gBackgroundThreadCount;
 static Beefy::SyncEvent gThreadsDoneEvent;
 static Beefy::SyncEvent gThreadsDoneEvent;
 
 
 #ifdef BF_PLATFORM_WINDOWS
 #ifdef BF_PLATFORM_WINDOWS
@@ -132,8 +133,12 @@ static void BF_CALLTYPE CStartProc(void* threadParam)
 
 
 	bool isAutoDelete = gBfRtCallbacks.Thread_IsAutoDelete(thread);
 	bool isAutoDelete = gBfRtCallbacks.Thread_IsAutoDelete(thread);
 	gBfRtCallbacks.Thread_ThreadProc(thread);
 	gBfRtCallbacks.Thread_ThreadProc(thread);
-	bool isLastThread = BfpSystem_InterlockedExchangeAdd32((uint32*)&gLiveThreadCount, -1) == 1;
+	
+	if (internalThread->mIsBackground)
+		BfpSystem_InterlockedExchangeAdd32((uint32*)&gBackgroundThreadCount, -1);
 
 
+	bool isLastThread = (int32)BfpSystem_InterlockedExchangeAdd32((uint32*)&gLiveThreadCount, -1) <= gBackgroundThreadCount + 1;
+		
     //printf("Stopping thread\n");
     //printf("Stopping thread\n");
 
 
 	bool wantsDelete = false;
 	bool wantsDelete = false;
@@ -158,7 +163,7 @@ static void BF_CALLTYPE CStartProc(void* threadParam)
 		delete internalThread;
 		delete internalThread;
 
 
 	if (isLastThread)
 	if (isLastThread)
-		gThreadsDoneEvent.Set(false);
+		gThreadsDoneEvent.Set(false);	
 
 
     //printf("Thread stopped\n");
     //printf("Thread stopped\n");
 }
 }
@@ -168,7 +173,7 @@ void BfInternalThread::WaitForAllDone()
 	if ((gBfRtFlags & BfRtFlags_NoThreadExitWait) != 0)
 	if ((gBfRtFlags & BfRtFlags_NoThreadExitWait) != 0)
 		return;
 		return;
 
 
-	while (gLiveThreadCount != 0)
+	while (gLiveThreadCount > gBackgroundThreadCount)
 	{
 	{
 		// Clear out any old done events
 		// Clear out any old done events
 		gThreadsDoneEvent.WaitFor();
 		gThreadsDoneEvent.WaitFor();
@@ -303,12 +308,23 @@ void Thread::InternalFinalize()
 
 
 bool Thread::IsBackgroundNative()
 bool Thread::IsBackgroundNative()
 {
 {
-	return false;
+	auto internalThread = GetInternalThread();
+	if (internalThread == NULL)
+		return false;
+	return internalThread->mIsBackground;
 }
 }
 
 
 void Thread::SetBackgroundNative(bool isBackground)
 void Thread::SetBackgroundNative(bool isBackground)
 {
 {
+	auto internalThread = GetInternalThread();
+	if (internalThread == NULL)
+		return;
 
 
+	if (isBackground != internalThread->mIsBackground)
+	{
+		internalThread->mIsBackground = isBackground;		
+		BfpSystem_InterlockedExchangeAdd32((uint32*)&gBackgroundThreadCount, isBackground ? 1 : -1);
+	}	
 }
 }
 
 
 int Thread::GetThreadStateNative()
 int Thread::GetThreadStateNative()

+ 2 - 0
BeefRT/rt/Thread.h

@@ -111,6 +111,7 @@ public:
 	bool mStarted;
 	bool mStarted;
 	bool mJoinOnDelete;
 	bool mJoinOnDelete;
 	bool mIsManualInit;
 	bool mIsManualInit;
+	bool mIsBackground;
 	BfpThread* mThreadHandle;
 	BfpThread* mThreadHandle;
 	intptr mThreadId;	
 	intptr mThreadId;	
 	Beefy::CritSect mCritSect;
 	Beefy::CritSect mCritSect;
@@ -126,6 +127,7 @@ public:
 		mIsSuspended = false;
 		mIsSuspended = false;
 		mJoinOnDelete = true;
 		mJoinOnDelete = true;
 		mIsManualInit = false;
 		mIsManualInit = false;
+		mIsBackground = false;
 		mStackStart = 0;
 		mStackStart = 0;
 		mThreadId = 0;
 		mThreadId = 0;
 	}
 	}