From 66f0ae9b344a1190280a7a5f0013eac7e50f5f2f Mon Sep 17 00:00:00 2001 From: Markus Ewald Date: Wed, 20 Jan 2010 20:21:23 +0000 Subject: [PATCH] The AffineThreadPool class will now work on Mono as well; fixed naming inconsistency for the EnumHelper class; inverted the counting direction used by the Semaphore class so it is easier to read (most other Semaphores count in the direction it is using now) git-svn-id: file:///srv/devel/repo-conversion/nusu@187 d2e56fa2-650e-0410-a79f-9358c0239efd --- Source/AffineThreadPool.cs | 26 ++++++++++++++------------ Source/EnumHelper.cs | 12 ++++++++---- Source/Semaphore.cs | 23 ++++++++++++----------- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/Source/AffineThreadPool.cs b/Source/AffineThreadPool.cs index 324114c..cad1b28 100644 --- a/Source/AffineThreadPool.cs +++ b/Source/AffineThreadPool.cs @@ -198,18 +198,20 @@ namespace Nuclex.Support { // be called from the thread whose affinity is being changed. Thread.CurrentThread.SetProcessorAffinity(new int[] { hardwareThreadIndex }); #else - // Prevent this managed thread from impersonating another system thread. - // In .NET, managed threads can supposedly be moved to different system threads - // and, more worryingly, even fibers. This should make sure we're sitting on - // a normal system thread and stay with that thread during our lifetime. - Thread.BeginThreadAffinity(); + if(Environment.OSVersion.Platform == PlatformID.Win32NT) { + // Prevent this managed thread from impersonating another system thread. + // In .NET, managed threads can supposedly be moved to different system threads + // and, more worryingly, even fibers. This should make sure we're sitting on + // a normal system thread and stay with that thread during our lifetime. + Thread.BeginThreadAffinity(); - // Assign the ideal processor, but don't force it. It's not a good idea to - // circumvent the thread scheduler of a desktop machine, so we try to play nice. - int threadId = GetCurrentThreadId(); - ProcessThread thread = GetProcessThread(threadId); - if(thread != null) { - thread.IdealProcessor = hardwareThreadIndex; + // Assign the ideal processor, but don't force it. It's not a good idea to + // circumvent the thread scheduler of a desktop machine, so we try to play nice. + int threadId = GetCurrentThreadId(); + ProcessThread thread = GetProcessThread(threadId); + if(thread != null) { + thread.IdealProcessor = hardwareThreadIndex; + } } #endif @@ -280,7 +282,7 @@ namespace Nuclex.Support { /// Delegate used to handle assertion checks in the code public static volatile ExceptionDelegate ExceptionHandler = DefaultExceptionHandler; -#if !XBOX360 +#if !XBOX360 // Only called if platform is Win32NT /// Retrieves the calling thread's thread id /// The thread is of the calling thread [DllImport("kernel32.dll")] diff --git a/Source/EnumHelper.cs b/Source/EnumHelper.cs index 98e56dc..4ff5019 100644 --- a/Source/EnumHelper.cs +++ b/Source/EnumHelper.cs @@ -70,14 +70,14 @@ namespace Nuclex.Support { // Look for the lowest value in the enumeration. We initialize the lowest value // to the first enumeration value so we don't have to use some arbitrary starting // value which might actually appear in the enumeration. - EnumType lowest = values[0]; + EnumType lowestValue = values[0]; for(int index = 1; index < values.Length; ++index) { - if(values[index].CompareTo(lowest) < 0) { - lowest = values[index]; + if(values[index].CompareTo(lowestValue) < 0) { + lowestValue = values[index]; } } - return lowest; + return lowestValue; } /// Retrieves a list of all values contained in an enumeration @@ -85,6 +85,10 @@ namespace Nuclex.Support { /// Type of the enumeration whose values will be returned /// /// All values contained in the specified enumeration + /// + /// This method produces collectable garbage so it's best to only call it once + /// and cache the result. + /// public static EnumType[] GetValues() { #if XBOX360 return GetValuesXbox360(); diff --git a/Source/Semaphore.cs b/Source/Semaphore.cs index 3084296..ca0749f 100644 --- a/Source/Semaphore.cs +++ b/Source/Semaphore.cs @@ -68,7 +68,7 @@ namespace Nuclex.Support { /// Number of users that can access the resource at the same time /// public Semaphore(int count) { - this.users = -count; + this.free = count; createEvent(); } @@ -87,7 +87,7 @@ namespace Nuclex.Support { ); } - this.users = initialCount - maximumCount; // should be negative! + this.free = maximumCount - initialCount; createEvent(); } @@ -129,11 +129,11 @@ namespace Nuclex.Support { // Lock the resource - even if it is full. We will correct out mistake later // if we overcomitted the resource. - int newUsers = Interlocked.Increment(ref this.users); + int newFree = Interlocked.Decrement(ref this.free); // If we got the resource, let the thread pass without further processing. - if(newUsers <= 0) { - if(newUsers < 0) { + if(newFree >= 0) { + if(newFree > 0) { this.manualResetEvent.Set(); } @@ -144,16 +144,17 @@ namespace Nuclex.Support { // moments ago, the resource was busy, so block the event. this.manualResetEvent.Reset(); Thread.MemoryBarrier(); - newUsers = Interlocked.Decrement(ref this.users); + newFree = Interlocked.Increment(ref this.free); // Unless we have been preempted by a Release(), we now have to wait for the // resource to become available. - if(newUsers >= 0) { + if(newFree >= 0) { if(!this.manualResetEvent.WaitOne(millisecondsTimeout, exitContext)) { return false; } } - } + + } // for(; ; ) } #if XBOX360 @@ -198,12 +199,12 @@ namespace Nuclex.Support { /// /// Releases a lock on the resource. Note that for a reverse counting semaphore, - /// it is legal to Release() the resource before before locking it. + /// it is legal to Release() the resource before locking it. /// public void Release() { // Release one lock on the resource - int newUsers = Interlocked.Decrement(ref this.users); + int newFree = Interlocked.Increment(ref this.free); // Wake up any threads waiting for the resource to become available this.manualResetEvent.Set(); @@ -227,7 +228,7 @@ namespace Nuclex.Support { /// Since this is a reverse counting semaphore, it will be negative if /// the resource is available and 0 if the semaphore is full. /// - private int users; + private int free; }