//////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: AutoResetEvent.cs // // Note: // using System; using System.Runtime.CompilerServices; using Microsoft.Singularity; using Microsoft.Singularity.Io; using Microsoft.Singularity.Scheduling; namespace System.Threading { [CLSCompliant(false)] public enum AutoResetEventEvent : ushort { Acquire = 1, Enqueue = 2 } //| [NoCCtor] [CLSCompliant(false)] public sealed class AutoResetEvent : WaitHandle { //| public AutoResetEvent(bool initialState) : base(initialState ? 1 : 0) { } //| [NoHeapAllocation] public bool Reset() { bool iflag = Processor.DisableInterrupts(); try { Scheduler.DispatchLock(); try { #if DEBUG_DISPATCH DebugStub.Print("Thread {0:x8} AutoResetEvent.Reset() on {1:x8}\n", __arglist( Kernel.AddressOf(Thread.CurrentThread), Kernel.AddressOf(this))); #endif // DEBUG_DISPATCH signaled = 0; } finally { Scheduler.DispatchRelease(); } } finally { Processor.RestoreInterrupts(iflag); } return true; } //| [NoHeapAllocation] public bool Set() { bool iflag = Processor.DisableInterrupts(); try { Scheduler.DispatchLock(); try { if (NotifyOne()) { #if DEBUG_DISPATCH DebugStub.Print("Thread {0:x8} AutoResetEvent.Set() on {1:x8}" + "unblocked {2:x8}\n", __arglist( Kernel.AddressOf(Thread.CurrentThread), Kernel.AddressOf(this), Kernel.AddressOf(owner))); #endif // DEBUG_DISPATCH signaled = 0; } else { #if DEBUG_DISPATCH DebugStub.Print("Thread {0:x8} AutoResetEvent.Set() on {1:x8} ready\n", __arglist( Kernel.AddressOf(Thread.CurrentThread), Kernel.AddressOf(this))); #endif // DEBUG_DISPATCH signaled = 1; } } finally { Scheduler.DispatchRelease(); } } finally { Processor.RestoreInterrupts(iflag); } return true; } //| public bool SetAll() { bool iflag = Processor.DisableInterrupts(); try { Scheduler.DispatchLock(); try { if (NotifyAll()) { signaled = 0; } else { signaled = 1; } } finally { Scheduler.DispatchRelease(); } } finally { Processor.RestoreInterrupts(iflag); } return true; } // Called with dispatch lock held and interrupts off. // Returns true if the AutoResetEvent was signaled. internal override bool AcquireOrEnqueue(ThreadEntry entry) { if (signaled != 0) { #if DEBUG_DISPATCH DebugStub.Print("Thread {0:x8} AutoResetEvent.Acquire on {1:x8}\n", __arglist( Kernel.AddressOf(Thread.CurrentThread), Kernel.AddressOf(this))); #endif // DEBUG_DISPATCH signaled = 0; Monitoring.Log(Monitoring.Provider.AutoResetEvent, (ushort)AutoResetEventEvent.Acquire, 0, (uint)this.id, (uint)entry.Thread.threadIndex, 0, 0, 0); return true; } else { #if DEBUG_DISPATCH DebugStub.Print("Thread {0:x8} AutoResetEvent.Enqueue on {1:x8}\n", __arglist( Kernel.AddressOf(Thread.CurrentThread), Kernel.AddressOf(this))); #endif // DEBUG_DISPATCH queue.EnqueueTail(entry); Monitoring.Log(Monitoring.Provider.AutoResetEvent, (ushort)AutoResetEventEvent.Enqueue, 0, (uint)this.id, (uint)entry.Thread.threadIndex, 0, 0, 0); return false; } } // Return thread who could use our priority. [NoHeapAllocation] internal override Thread GetBeneficiary() { return null; } } }