/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: Scheduler.cs // // Note: // //#define DEBUG_SCHEDULER using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Threading; using Microsoft.Singularity; using Microsoft.Singularity.Hal; using Microsoft.Singularity.Io; namespace Microsoft.Singularity.Scheduling { [NoCCtor] [CLSCompliant(false)] [AccessedByRuntime("referenced from halidt.asm")] public abstract class Scheduler { /// /// /// Constructor - is used to generate scheduler Ids /// /// protected Scheduler() { } public abstract void Initialize(); [CLSCompliant(false)] public abstract void Finalize(); [CLSCompliant(false)] public abstract void OnDispatcherInitialize(int dispatcherId); [CLSCompliant(false)] public abstract void OnThreadStateInitialize(Thread thread, bool constructorCalled); [CLSCompliant(false)] public abstract void OnThreadStart(Thread thread); [CLSCompliant(false)] public abstract void OnThreadBlocked(Thread thread, SchedulerTime stop); [CLSCompliant(false)] [NoHeapAllocation] public abstract void OnThreadUnblocked(Thread thread); [CLSCompliant(false)] [NoHeapAllocation] public abstract void OnThreadYield(Thread thread); [CLSCompliant(false)] public abstract void OnThreadStop(Thread thread); [CLSCompliant(false)] [NoHeapAllocation] public abstract void OnThreadFreezeIncrement(Thread thread); [CLSCompliant(false)] [NoHeapAllocation] public abstract void OnThreadFreezeDecrement(Thread thread); [CLSCompliant(false)] [NoHeapAllocation] public abstract TimeSpan OnTimerInterrupt(int affinity, SchedulerTime now); [CLSCompliant(false)] [NoHeapAllocation] public static bool IsIdleThread (int threadIdx) { return ProcessorDispatcher.IsIdleThread(threadIdx); } [CLSCompliant(false)] [NoHeapAllocation] public abstract void AddRunnableThread(Thread thread); /// /// /// Run scheduling policy to decide the next thread to run /// /// /// Set the returned running thread to this affinity. /// the thread currently running /// thread state to change to for the current thread /// Current system time /// [CLSCompliant(false)] [NoHeapAllocation] public abstract Thread RunPolicy( int affinity, Thread currentThread, ThreadState schedulerAction, SchedulerTime currentTime); [CLSCompliant(false)] [NoHeapAllocation] public abstract void Suspend(Thread thread); [CLSCompliant(false)] [NoHeapAllocation] public abstract void Resume(Thread thread); /// /// /// Scheduler hints for enquing threads /// /// [Flags] public enum Hint { Head = 0, Tail = 1, } /// /// /// Retrieve scheduler lock - used by dispatcher to protect scheduler state /// /// [CLSCompliant(false)] [NoHeapAllocation] internal abstract SchedulerLock RetrieveSchedulerLock(int affinity); } /// /// /// Scheduler lock class is used to wrap a spinlock structure so that it can be shared with a /// dispatcher. /// /// [NoCCtor] [CLSCompliant(false)] [AccessedByRuntime("referenced from halidt.asm")] internal class SchedulerLock { /// /// /// Constructor /// /// public SchedulerLock() { // Initialize spinlock this.spinlock = new SpinLock(SpinLock.Types.Scheduler); } /// /// /// A method is used to acquire scheduler lock /// /// [NoHeapAllocation] public void Acquire(Thread currentThread) { this.spinlock.Acquire(currentThread); } /// /// /// A method is used to release scheduler lock /// /// [NoHeapAllocation] public void Release(Thread currentThread) { this.spinlock.Release(currentThread); } /// /// /// A method is used to acquire scheduler lock /// /// [NoHeapAllocation] public void Acquire() { this.spinlock.Acquire(); } /// /// /// Try to acquire the spin lock. Always return immediately. /// /// true if the spin lock is acquired. /// [NoHeapAllocation] public bool TryAcquire() { return this.spinlock.TryAcquire(); } /// /// /// A method is used to release scheduler lock /// /// [NoHeapAllocation] public void Release() { this.spinlock.Release(); } /// /// /// Check if thread holds the spinlock /// /// [NoHeapAllocation] public bool IsHeldBy(Thread currentThread) { return this.spinlock.IsHeldBy(currentThread); } /// Actual spinlock that class wraps [AccessedByRuntime("referenced from halidt.asm")] private SpinLock spinlock; } }