Browse Source

2001-11-26 Dick Porter <[email protected]>

	* Thread.cs: DataSlot uses a single system TLS slot, and a
	hashtable per thread.  Some minor changes to reflect the new
	internal calls using the new IO library, and the newly-supported
	bool returns from internal calls.

	* Monitor.cs: Use bool returns from internal calls now they are
	supported by the runtime.  Coalesce enter with the try_enter
	internal call.

2001-11-26  Dick Porter  <[email protected]>

	* LocalDataStoreSlot.cs: No need to delete a system TLS slot in
	the finalise routine any more

svn path=/trunk/mcs/; revision=1441
Dick Porter 24 years ago
parent
commit
d3f63d2d18

+ 10 - 0
mcs/class/corlib/System.Threading/ChangeLog

@@ -1,3 +1,13 @@
+2001-11-26  Dick Porter  <[email protected]>
+
+	* Thread.cs: DataSlot uses a single system TLS slot, and a
+	hashtable per thread.  Some minor changes to reflect the new
+	internal calls using the new IO library, and the newly-supported
+	bool returns from internal calls.
+
+	* Monitor.cs: Use bool returns from internal calls now they are
+	supported by the runtime.  Coalesce enter with the try_enter
+	internal call.
 
 Wed Nov 14 17:06:18 CET 2001 Paolo Molaro <[email protected]>
 

+ 20 - 25
mcs/class/corlib/System.Threading/Monitor.cs

@@ -13,10 +13,11 @@ namespace System.Threading
 {
 	public sealed class Monitor
 	{
-		// Grabs the mutex on object 'obj'
+		// Grabs the mutex on object 'obj', with a maximum
+		// wait time 'ms' but doesn't block - if it can't get
+		// the lock it returns false, true if it can
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static void Monitor_enter(object obj);
-		
+		private extern static bool Monitor_try_enter(object obj, int ms);
 		public static void Enter(object obj) {
 			if(obj==null) {
 				throw new ArgumentNullException("Object is null");
@@ -25,7 +26,7 @@ namespace System.Threading
 			//	throw new ArgumentException("Value type");
 			//}
 
-			Monitor_enter(obj);
+			Monitor_try_enter(obj, Timeout.Infinite);
 		}
 
 		// Releases the mutex on object 'obj'
@@ -35,7 +36,7 @@ namespace System.Threading
 		// Checks whether the current thread currently owns
 		// the lock on object 'obj'
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static /*bool*/ int Monitor_test_owner(object obj);
+		private extern static bool Monitor_test_owner(object obj);
 		
 		public static void Exit(object obj) {
 			if(obj==null) {
@@ -45,7 +46,7 @@ namespace System.Threading
 			//	throw new ArgumentException("Value type");
 			//}
 
-			if(Monitor_test_owner(obj)==/*false*/0) {
+			if(Monitor_test_owner(obj)==false) {
 				throw new SynchronizationLockException("The current thread does not own the lock");
 			}
 			
@@ -59,13 +60,13 @@ namespace System.Threading
 
 		// Checks whether object 'obj' is currently synchronised
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static /*bool*/ int Monitor_test_synchronised(object obj);
+		private extern static bool Monitor_test_synchronised(object obj);
 
 		public static void Pulse(object obj) {
 			if(obj==null) {
 				throw new ArgumentNullException("Object is null");
 			}
-			if(Monitor_test_synchronised(obj)==/*false*/0) {
+			if(Monitor_test_synchronised(obj)==false) {
 				throw new SynchronizationLockException("Object is not synchronised");
 			}
 
@@ -81,19 +82,13 @@ namespace System.Threading
 			if(obj==null) {
 				throw new ArgumentNullException("Object is null");
 			}
-			if(Monitor_test_synchronised(obj)==/*false*/0) {
+			if(Monitor_test_synchronised(obj)==false) {
 				throw new SynchronizationLockException("Object is not synchronised");
 			}
 
 			Monitor_pulse_all(obj);
 		}
 
-		// Grabs the mutex on object 'obj', with a maximum
-		// wait time 'ms' but doesn't block - if it can't get
-		// the lock it returns false, true if it can
-		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static /*bool*/ int Monitor_try_enter(object obj, int ms);
-
 		public static bool TryEnter(object obj) {
 			if(obj==null) {
 				throw new ArgumentNullException("Object is null");
@@ -102,7 +97,7 @@ namespace System.Threading
 			//	throw new ArgumentException("Value type");
 			//}
 			
-			return((Monitor_try_enter(obj, 0)==1));
+			return(Monitor_try_enter(obj, 0));
 		}
 
 		public static bool TryEnter(object obj, int millisecondsTimeout) {
@@ -124,7 +119,7 @@ namespace System.Threading
 				throw new ArgumentException("millisecondsTimeout negative");
 			}
 			
-			return((Monitor_try_enter(obj, millisecondsTimeout)==1));
+			return(Monitor_try_enter(obj, millisecondsTimeout));
 		}
 
 		public static bool TryEnter(object obj, TimeSpan timeout) {
@@ -147,36 +142,36 @@ namespace System.Threading
 				throw new ArgumentOutOfRangeException("timeout out of range");
 			}
 			
-			return((Monitor_try_enter(obj, timeout.Milliseconds)==1));
+			return(Monitor_try_enter(obj, timeout.Milliseconds));
 		}
 
 		// Waits for a signal on object 'obj' with maximum
 		// wait time 'ms'. Returns true if the object was
 		// signalled, false if it timed out
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static /*bool*/ int Monitor_wait(object obj, int ms);
+		private extern static bool Monitor_wait(object obj, int ms);
 
 		public static bool Wait(object obj) {
 			if(obj==null) {
 				throw new ArgumentNullException("Object is null");
 			}
-			if(Monitor_test_synchronised(obj)==/*false*/0) {
+			if(Monitor_test_synchronised(obj)==false) {
 				throw new SynchronizationLockException("Object is not synchronised");
 			}
 
-			return((Monitor_wait(obj, 0)==1));
+			return(Monitor_wait(obj, 0));
 		}
 
 		public static bool Wait(object obj, int millisecondsTimeout) {
 			if(obj==null) {
 				throw new ArgumentNullException("Object is null");
 			}
-			if(Monitor_test_synchronised(obj)==/*false*/0) {
+			if(Monitor_test_synchronised(obj)==false) {
 				throw new SynchronizationLockException("Object is not synchronised");
 			}
 			// LAMESPEC: no mention of timeout sanity checking
 
-			return((Monitor_wait(obj, millisecondsTimeout)==1));
+			return(Monitor_wait(obj, millisecondsTimeout));
 		}
 
 		public static bool Wait(object obj, TimeSpan timeout) {
@@ -187,11 +182,11 @@ namespace System.Threading
 			if(timeout.Milliseconds < 0 || timeout.Milliseconds > Int32.MaxValue) {
 				throw new ArgumentOutOfRangeException("timeout out of range");
 			}
-			if(Monitor_test_synchronised(obj)==/*false*/0) {
+			if(Monitor_test_synchronised(obj)==false) {
 				throw new SynchronizationLockException("Object is not synchronised");
 			}
 
-			return((Monitor_wait(obj, timeout.Milliseconds)==1));
+			return(Monitor_wait(obj, timeout.Milliseconds));
 		}
 
 		public static bool Wait(object obj, int millisecondsTimeout, bool exitContext) {

+ 46 - 64
mcs/class/corlib/System.Threading/Thread.cs

@@ -48,15 +48,29 @@ namespace System.Threading
 			}
 		}
 
-		// Registers a new LocalDataStoreSlot with a thread key.
+		// Looks up the slot hash for the current thread
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static void DataSlot_register(LocalDataStoreSlot slot);
-		
+		private extern static Hashtable SlotHash_lookup();
+
+		// Stores the slot hash for the current thread
+		[MethodImplAttribute(MethodImplOptions.InternalCall)]
+		private extern static void SlotHash_store(Hashtable slothash);
+
+		private static Hashtable GetTLSSlotHash() {
+			Hashtable slothash=SlotHash_lookup();
+			if(slothash==null) {
+				// Not synchronised, because this is
+				// thread specific anyway.
+				slothash=new Hashtable();
+				SlotHash_store(slothash);
+			}
+
+			return(slothash);
+		}
+
 		public static LocalDataStoreSlot AllocateDataSlot() {
 			LocalDataStoreSlot slot = new LocalDataStoreSlot();
-			
-			DataSlot_register(slot);
-			
+
 			return(slot);
 		}
 
@@ -75,8 +89,6 @@ namespace System.Threading
 
 			datastorehash.Add(name, slot);
 			
-			DataSlot_register(slot);
-			
 			return(slot);
 		}
 
@@ -84,16 +96,13 @@ namespace System.Threading
 			LocalDataStoreSlot slot=(LocalDataStoreSlot)datastorehash[name];
 
 			if(slot!=null) {
-				// FIXME
+				datastorehash.Remove(slot);
 			}
 		}
 
-		// Retrieves an object from slot 'slot' in this thread
-		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static object DataSlot_retrieve(LocalDataStoreSlot slot);
-
 		public static object GetData(LocalDataStoreSlot slot) {
-			return(DataSlot_retrieve(slot));
+			Hashtable slothash=GetTLSSlotHash();
+			return(slothash[slot]);
 		}
 
 		public static AppDomain GetDomain() {
@@ -120,42 +129,25 @@ namespace System.Threading
 			// FIXME
 		}
 
-		// Stores 'data' into slot 'slot' in this thread
-		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static void DataSlot_store(LocalDataStoreSlot slot, object data);
-		
-		public static void SetData(LocalDataStoreSlot slot, object data) {
-			DataSlot_store(slot, data);
+		public static void SetData(LocalDataStoreSlot slot,
+					   object data) {
+			Hashtable slothash=GetTLSSlotHash();
+			slothash.Add(slot, data);
 		}
 
-		// Returns milliseconds remaining (due to interrupted sleep)
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static int Sleep_internal(int ms);
+		private extern static void Sleep_internal(int ms);
 
-		// Causes thread to give up its timeslice
-		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern static void Schedule_internal();
-		
 		public static void Sleep(int millisecondsTimeout) {
 			if(millisecondsTimeout<0) {
 				throw new ArgumentException("Negative timeout");
 			}
-			if(millisecondsTimeout==0) {
-				// Schedule another thread
-				Schedule_internal();
-			} else {
-				Thread thread=CurrentThread;
+			Thread thread=CurrentThread;
 				
-				thread.set_state(ThreadState.WaitSleepJoin);
+			thread.set_state(ThreadState.WaitSleepJoin);
 				
-				int ms_remaining=Sleep_internal(millisecondsTimeout);
-				thread.clr_state(ThreadState.WaitSleepJoin);
-
-				if(ms_remaining>0) {
-					throw new ThreadInterruptedException("Thread interrupted while sleeping");
-				}
-			}
-			
+			Sleep_internal(millisecondsTimeout);
+			thread.clr_state(ThreadState.WaitSleepJoin);
 		}
 
 		public static void Sleep(TimeSpan timeout) {
@@ -163,30 +155,20 @@ namespace System.Threading
 			if(timeout.Milliseconds < 0 || timeout.Milliseconds > Int32.MaxValue) {
 				throw new ArgumentOutOfRangeException("Timeout out of range");
 			}
-			if(timeout.Milliseconds==0) {
-				// Schedule another thread
-				Schedule_internal();
-			} else {
-				Thread thread=CurrentThread;
-				
-				thread.set_state(ThreadState.WaitSleepJoin);
-				int ms_remaining=Sleep_internal(timeout.Milliseconds);
-				thread.clr_state(ThreadState.WaitSleepJoin);
+
+			Thread thread=CurrentThread;
 				
-				if(ms_remaining>0) {
-					throw new ThreadInterruptedException("Thread interrupted while sleeping");
-				}
-			}
+			thread.set_state(ThreadState.WaitSleepJoin);
+			Sleep_internal(timeout.Milliseconds);
+			thread.clr_state(ThreadState.WaitSleepJoin);
 		}
 
-		// stores a pthread_t, which is defined as unsigned long
-		// on my system.  I _think_ windows uses "unsigned int" for
-		// its thread handles, so that _should_ work too.
-		private UInt32 system_thread_handle;
+		// stores a thread handle
+		private IntPtr system_thread_handle;
 
 		// Returns the system thread handle
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern UInt32 Thread_internal(ThreadStart start);
+		private extern IntPtr Thread_internal(ThreadStart start);
 
 		public Thread(ThreadStart start) {
 			if(start==null) {
@@ -308,7 +290,7 @@ namespace System.Threading
 		// The current thread joins with 'this'. Set ms to 0 to block
 		// until this actually exits.
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern /* FIXME waiting for impl in mono_create trampoline bool*/ int Join_internal(int ms, UInt32 handle);
+		private extern bool Join_internal(int ms, IntPtr handle);
 		
 		public void Join() {
 			if((state & ThreadState.Unstarted) != 0) {
@@ -333,8 +315,8 @@ namespace System.Threading
 			Thread thread=CurrentThread;
 				
 			thread.set_state(ThreadState.WaitSleepJoin);
-			bool ret=(Join_internal(millisecondsTimeout,
-						system_thread_handle)==1);
+			bool ret=Join_internal(millisecondsTimeout,
+					       system_thread_handle);
 			thread.clr_state(ThreadState.WaitSleepJoin);
 
 			return(ret);
@@ -352,8 +334,8 @@ namespace System.Threading
 			Thread thread=CurrentThread;
 
 			thread.set_state(ThreadState.WaitSleepJoin);
-			bool ret=(Join_internal(timeout.Milliseconds,
-						system_thread_handle)==1);
+			bool ret=Join_internal(timeout.Milliseconds,
+					       system_thread_handle);
 			thread.clr_state(ThreadState.WaitSleepJoin);
 
 			return(ret);
@@ -365,7 +347,7 @@ namespace System.Threading
 
 		// Launches the thread
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern void Start_internal(UInt32 handle);
+		private extern void Start_internal(IntPtr handle);
 		
 		public void Start() {
 			if((state & ThreadState.Unstarted) == 0) {

+ 2 - 1
mcs/class/corlib/System.Threading/ThreadPool.cs

@@ -22,7 +22,8 @@ namespace System.Threading
 			return(false);
 		}
 
-		public static bool QueueUserWorkItem(WaitCallback callback, object state) {
+		public static bool QueueUserWorkItem(WaitCallback callback,
+						     object state) {
 			// FIXME
 			return(false);
 		}

+ 5 - 0
mcs/class/corlib/System/ChangeLog

@@ -1,3 +1,8 @@
+2001-11-26  Dick Porter  <[email protected]>
+
+	* LocalDataStoreSlot.cs: No need to delete a system TLS slot in
+	the finalise routine any more
+
 2001-11-21  Miguel de Icaza  <[email protected]>
 
 	* ApplicationException.cs: internationalize by adding calls to

+ 0 - 8
mcs/class/corlib/System/LocalDataStoreSlot.cs

@@ -14,13 +14,5 @@ namespace System
 {
 	public sealed class LocalDataStoreSlot
 	{
-		// Need to remove the thread system's data slot,
-		// therefore this internalcall is in the threads code
-		[MethodImplAttribute(MethodImplOptions.InternalCall)]
-		private extern void DataSlot_unregister();
-		
-		~LocalDataStoreSlot() {
-			DataSlot_unregister();
-		}
 	}
 }