singrdk/base/Kernel/Singularity/Scheduling/Laxity/LaxityActivity.cs

135 lines
4.8 KiB
C#
Raw Normal View History

2008-03-05 09:52:00 -05:00
////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: LaxityActivity.cs
//
// Note:
//
using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.Singularity.Scheduling;
namespace Microsoft.Singularity.Scheduling.Laxity
{
/// <summary>
/// The resource container class includes a recurring reservation
/// (k out of every n), a list of runnable threads, unfinished constraints
/// (i.e. non-guaranteed or non-feasible), as well as pointers to handle
/// its role in lists for the non-blocked activity list.
/// It also has references for the last node to execute it,
/// a node assigned to it (which is a list via SameActivityNext), and a node
/// assigned to it under the new scheduling plan. It also has some bookkeeping.
/// </summary>
public class LaxityActivity : ISchedulerActivity
{
Activity enclosingActivity;
public RecurringReservation MyRecurringCpuReservation;
public LaxityThread RunnableThreads;// list of runnable threads, if any
#if false
public OneShotReservation UnfinishedConstraints;
#endif
public LaxityActivity Next; // Next and previous activities
public LaxityActivity Previous;
public int ReferenceCount;
public int CountNodes;
public LaxityActivity()
{
//Below is InitializeActivity();
ReferenceCount = 1;
RunnableThreads = null;
// MyRecurringCpuReservation = new RecurringReservation();
// MyRecurringCpuReservation.EnclosingCpuReservation = new CpuResourceReservation(MyRecurringCpuReservation);
bool iflag = Processor.DisableInterrupts();
LaxityScheduler.EnqueueActivity(this); // add in last position in Laxity!
Processor.RestoreInterrupts(iflag);
}
public void ReleaseActivity()
{
bool iflag = Processor.DisableInterrupts();
LaxityScheduler.DequeueActivity(this); // update Laxity queue, if required.
Processor.RestoreInterrupts(iflag);
Scheduler.LogDeleteActivity();
}
//public-normal API
//TODO: Call this from finalize?
public override void ReleaseReference()
{
// DI replaced by AtomicDec(&activity->ReferenceCount);
Debug.Assert(ReferenceCount > 0);
int newrefcnt = Interlocked.Decrement(ref ReferenceCount);
if (newrefcnt == CountNodes) {
if (CountNodes > 0) {
return;
}
bool iflag = Processor.DisableInterrupts();
LaxityScheduler.DequeueActivity(this); // update Laxity queue, if required.
Processor.RestoreInterrupts(iflag);
}
Scheduler.LogDeleteActivity();
}
// find the runnable thread of an activity:
public LaxityThread GetRunnableThread()
{
// dnarayan: we don't schedule tasks from resource containers anymore,
// but directly from the global least-laxity heap
#if false
OneShotReservation reservation = UnfinishedConstraints;
Debug.Assert(reservation == null || reservation.AssociatedActivity == null);
// avoid stack overflow : GetRunnableThread & GetRunnableThread
while (reservation != null) {
// search in the circular list
LaxityThread thread = reservation.GetRunnableThread();
if (thread != null) {
return thread;
}
reservation = reservation.Next;
if (reservation == UnfinishedConstraints) {
break;
}
}
#endif
LaxityThread runThread = RunnableThreads;
while (runThread != null && runThread.ActiveProcessor != null && runThread != RunnableThreads.Previous) {
runThread = runThread.Next;
}
if (runThread == null || runThread.ActiveProcessor != null) {
return null;
}
else {
return runThread;
}
}
#region ISchedulerActivity Members
public override Activity EnclosingActivity
{
get { return enclosingActivity; }
set { enclosingActivity = value; }
}
public CpuResourceReservation CpuResourceReservation
{
get { return MyRecurringCpuReservation.EnclosingCpuReservation; }
}
#endregion
}
}