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