/// <summary> /// Builds the heap down. /// </summary> /// <param name="k">the k-th element to start from.</param> public void BuildDown(int k) { int child = k; for (; 2 * child + 1 < size; k = child) { // local subtree root ISchedulableThread root = items[k]; // left child. child = 2 * k + 1; // if left child is bigger then the right then pick the right. if (child != size - 1 && items[child].CompareTo(items[child + 1]) > 0) { child++; } // now compare with root if (root.CompareTo(items[child]) > 0) { if (max.CompareTo(items[child]) < 0) { max = items[child]; } // swamp items[k] = items[child]; items[child] = root; items[k].SchedulableIndex = k; items[child].SchedulableIndex = child; } } }
/// <summary> /// Updates the specified value at k-th element. /// </summary> /// <param name="k">the element index to update.</param> /// <param name="item">the specified item value.</param> public void Update(int k, ISchedulableThread item) { items[k] = item; // start as a parent as check for build up is faster. int childOrParrent = (k - 1) / 2; // first check if we should build up or down. if (CheckAndBuildUp(k, childOrParrent, item)) { return; } childOrParrent = k * 2 + 1; // check the left child. if (CheckAndBuildDown(k, childOrParrent, item)) { return; } // check the right child. childOrParrent++; if (CheckAndBuildDown(k, childOrParrent, item)) { return; } }
public void Reschedule(Threading.ISchedulableThread caller, SchedulerAction action) { var scheduler = threadScheduler; int min = scheduler[0].Count; int minId = 0; int max = scheduler[0].Count; int maxId = 0; for (int i = 0; i < scheduler.Length; i++) { var cnt = scheduler[i].Count; if (min > cnt) { min = cnt; minId = i; } else if (max <= cnt) { max = cnt; maxId = i; } } bestThread = scheduler[minId]; worstThread = scheduler[maxId]; }
/// <summary> /// Builds the heap up. /// </summary> /// <param name="k">the k-th element to start from.</param> private void BuildUp(int k) { int parent = k; for (; k > 1; k = parent) { // local subtree root ISchedulableThread root = items[k]; parent = (k - 1) / 2; // check my parent, if im smaller then him then swamp if (root.CompareTo(items[parent]) > 0) { if (max.CompareTo(items[parent]) <= 0) { max = items[parent]; } items[k] = items[parent]; items[parent] = root; items[k].SchedulableIndex = k; items[parent].SchedulableIndex = parent; } } }
public void Add(ISchedulableThread thread) { lock (locker) { threadScheduler.Insert(thread); } }
/// <summary> /// A default static constructor that initializes the pool threads. /// </summary> static SmartThreadPool() { //create a scheduler for threads created outside the computation system. //By default this is a heap scheduller since there can be much more threads, //thus heap sort is more efficient. artificialThreadScheduler = Configuration.ArtificialThreadScheduler; uint physicalProcessors = Unsafe.GetPhysicalCores(); //the idea here is {core_count} * 2 the rest should be spawned as fibers. ISchedulableThread[] threads = new ISchedulableThread[physicalProcessors * 2]; for (int i = 0; i < threads.Length; i++) { threads[i] = new SmartThread(true, -1); threads[i].SchedulableIndex = i; if (Configuration.SmartThreadPoolPreLoadThreads) { threads[i].Start(); } } //Load the default thread scheduler. threadScheduler = Configuration.SmartPoolScheduler; threadScheduler.Create(threads); }
public void Remove(ISchedulableThread thread) { lock (locker) { threadScheduler.Remove(thread); } }
/// <summary> /// Initializes the heap that takes the input array, to construct the heap. /// </summary> /// <param name="array">Generic array.</param> public Heap(ISchedulableThread[] array) { this.items = array; if (array.Length != 0) max = this.items[0]; size = array.Length; BuildHeap(); }
static FiberPool() { ISchedulableThread[] threads = new ISchedulableThread[fiberThreadCount]; for (int i = 0; i < fiberThreadCount; i++) threads[i] = new FiberThread(); fiberScheduler = Configuration.FiberPoolScheduler; fiberScheduler.Create(threads); }
/// <summary> /// Initializes the heap that takes the input array, to construct the heap. /// </summary> /// <param name="array">Generic array.</param> public Heap(ISchedulableThread[] array) { this.items = array; if (array.Length != 0) { max = this.items[0]; } size = array.Length; BuildHeap(); }
public void Create(Threading.ISchedulableThread[] threads) { threadScheduler = threads; ThreadCount = threadScheduler.Length; bestThread = threadScheduler[0]; worstThread = threadScheduler[0]; IsCreated = true; }
static FiberPool() { ISchedulableThread[] threads = new ISchedulableThread[fiberThreadCount]; for (int i = 0; i < fiberThreadCount; i++) { threads[i] = new FiberThread(); } fiberScheduler = Configuration.FiberPoolScheduler; fiberScheduler.Create(threads); }
/// <summary> /// Deletes the minimum element from the heap. /// </summary> /// <returns></returns> public ISchedulableThread DeleteMin() { //get min and ovveride it, with the next array element. ISchedulableThread min = items[0]; items[0] = items[--size]; //build the heap down. BuildDown(0); return(min); }
/// <summary> /// Atempts to rebuild the pririty queue, to contain correct information /// about priorities. /// </summary> /// <param name="threadPoolThread">boolean value idnicating that we want threads that /// were created in a threadpool.</param> internal static void Reschedule(bool threadPoolThread, ISchedulableThread @this, SchedulerAction action) { if (threadPoolThread) { //we don't need to lock this section as generally we are ok //with the race as it will not cause any errors but putting a simple //flag arround it should be enough to prevent most races. threadScheduler.Reschedule(@this, action); return; } artificialThreadScheduler.Reschedule(@this, action); }
/// <summary> /// Checks if k-th element is smaller then it's parent and builds up /// if that yeilds true. /// </summary> /// <param name="k">k-th element.</param> /// <param name="parent">the parent.</param> /// <param name="item">the value of k-th element.</param> /// <returns>boolean value indicating that the heap was build up.</returns> private bool CheckAndBuildUp(int k, int parent, ISchedulableThread item) { if (parent > 0 && item.CompareTo(items[parent]) < 0) { items[k] = items[parent]; items[parent] = item; items[k].SchedulableIndex = k; items[parent].SchedulableIndex = parent; BuildUp(parent); return(true); } return(false); }
public void Reschedule(ISchedulableThread owner, SchedulerAction action) { if (threadScheduler.IsBuilding == false) { //We need this lock as our underlying heap implementation //is not thread safe atm, in the future TODO: this will change //as we will move to other DS or use fine grained or lock free heaps. if (Monitor.TryEnter(locker)) { threadScheduler.IsBuilding = true; threadScheduler.Update(owner.SchedulableIndex, owner); Monitor.Exit(locker); threadScheduler.IsBuilding = false; } } }
public static void QueueWorkItem(IComputation computation) { ISchedulableThread lowestWorkloadThread = null; lowestWorkloadThread = threadScheduler.GetScheduledThread(); //If a thread is not started then do Start it. if (lowestWorkloadThread.IsStarted == false) { lowestWorkloadThread.Start(); } //schedule a task. lowestWorkloadThread.Execute(computation); threadScheduler.Reschedule(lowestWorkloadThread, SchedulerAction.Enqueue); }
/// <summary> /// Checks if k-th element is bigger then it's parent and builds down /// if that yeilds true. /// </summary> /// <param name="k">k-th element.</param> /// <param name="parent">the parent.</param> /// <param name="item">the value of k-th element.</param> /// <returns>boolean value indicating that the heap was build down.</returns> private bool CheckAndBuildDown(int k, int child, ISchedulableThread item) { if (child != items.Length && child < items.Length && item.CompareTo(items[child]) > 0) { // swamp items[k] = items[child]; items[child] = item; items[k].SchedulableIndex = k; items[child].SchedulableIndex = child; BuildDown(child); return(true); } return(false); }
/// <summary> /// Inserts a new item into the heap. /// </summary> /// <param name="item">item to be added.</param> public void Insert(ISchedulableThread item) { if (size == items.Length) { Expand(); } int k = ++size - 1; items[k] = item; if (max == null) { max = item; } BuildUp(k); }
public static void QueueWorkItem(IComputation computation) { ISchedulableThread fiber = fiberScheduler.GetScheduledThread(); if (!fiber.IsStarted) { fiber.Start(); } //This code was commented out as upon fiber framework start we are creating //up front many fiber threads therefor it's pointless to exmpand even more //as it's hard to define a criteria how to expand. // //if (((FiberThread)fiber).ComputationCount >= nextFiberThreashold) // fiberScheduler.Add(new FiberThread()); fiber.Execute(computation); }
public void Remove(ISchedulableThread thread) { int cnt = 0; ISchedulableThread[] shortItems = new ISchedulableThread[--size]; //the linear search in this context should not be to big of a problem, //as if we join then this means that probably our queue is empty so we should //be somwhere in the top of the tree. foreach (ISchedulableThread currentThread in items) { if (currentThread.ThreadId != thread.ThreadId) { shortItems[cnt] = currentThread; cnt++; } } items = shortItems; }
/// <summary> /// Checks if k-th element is bigger then it's parent and builds down /// if that yeilds true. /// </summary> /// <param name="k">k-th element.</param> /// <param name="parent">the parent.</param> /// <param name="item">the value of k-th element.</param> /// <returns>boolean value indicating that the heap was build down.</returns> private bool CheckAndBuildDown(int k, int child, ISchedulableThread item) { if (child != items.Length && child < items.Length && item.CompareTo(items[child]) > 0) { // swamp items[k] = items[child]; items[child] = item; items[k].SchedulableIndex = k; items[child].SchedulableIndex = child; BuildDown(child); return true; } return false; }
public void Reschedule(ISchedulableThread owner, SchedulerAction action) { if (isBuilding == False) { //We need this lock as our underlying implementation //is not thread safe atm, in the future TODO: this will change //as we will move to other DS or use fine grained locks. int local = isBuilding; if (Interlocked.CompareExchange(ref isBuilding, 1, local) == 0) { var copy = threadScheduler[owner.SchedulableIndex]; if (action == SchedulerAction.Enqueue || action == SchedulerAction.Steal) { var indexPlus = owner.SchedulableIndex + 1; while (threadScheduler.Length - 1 != owner.SchedulableIndex) { var plusThread = threadScheduler[indexPlus]; if (copy.CompareTo(plusThread) > 0) { plusThread.SchedulableIndex--; threadScheduler[owner.SchedulableIndex] = plusThread; threadScheduler[indexPlus] = copy; owner.SchedulableIndex++; indexPlus = owner.SchedulableIndex + 1; } else { break; } } } else if (action == SchedulerAction.Dequeue) { var indexMinus = owner.SchedulableIndex - 1; while (owner.SchedulableIndex != 0) { var minusThread = threadScheduler[indexMinus]; if (copy.CompareTo(minusThread) < 0) { minusThread.SchedulableIndex++; threadScheduler[owner.SchedulableIndex] = minusThread; threadScheduler[indexMinus] = copy; owner.SchedulableIndex--; indexMinus = owner.SchedulableIndex - 1; } else { break; } } } isBuilding = False; } } }
public ISchedulableThread GetScheduledThread() { ISchedulableThread thread = threadScheduler.ReadMin(); return(thread); }
public int CompareTo(ISchedulableThread other) { return(this.scheduler.Count - ((FiberThread)other).scheduler.Count); }
/// <summary> /// Inserts a new item into the heap. /// </summary> /// <param name="item">item to be added.</param> public void Insert(ISchedulableThread item) { if (size == items.Length) Expand(); int k = ++size - 1; items[k] = item; if (max == null) max = item; BuildUp(k); }
/// <summary> /// Builds the heap up. /// </summary> /// <param name="k">the k-th element to start from.</param> private void BuildUp(int k) { int parent = k; for (; k > 1; k = parent) { // local subtree root ISchedulableThread root = items[k]; parent = (k - 1) / 2; // check my parent, if im smaller then him then swamp if (root.CompareTo(items[parent]) > 0) { if (max.CompareTo(items[parent]) <= 0) max = items[parent]; items[k] = items[parent]; items[parent] = root; items[k].SchedulableIndex = k; items[parent].SchedulableIndex = parent; } } }
/// <summary> /// Updates the specified value at k-th element. /// </summary> /// <param name="k">the element index to update.</param> /// <param name="item">the specified item value.</param> public void Update(int k, ISchedulableThread item) { items[k] = item; // start as a parent as check for build up is faster. int childOrParrent = (k - 1) / 2; // first check if we should build up or down. if (CheckAndBuildUp(k, childOrParrent, item)) return; childOrParrent = k * 2 + 1; // check the left child. if (CheckAndBuildDown(k, childOrParrent, item)) return; // check the right child. childOrParrent++; if (CheckAndBuildDown(k, childOrParrent, item)) return; }
// Actually threads should not be comparable :( // TODO: Create a comparable inner class. public int CompareTo(ISchedulableThread other) { return(this.scheduler.UnsafeCount - ((SmartThread)other).scheduler.UnsafeCount); }
public int CompareTo(ISchedulableThread other) { return this.scheduler.Count - ((FiberThread)other).scheduler.Count; }
/// <summary> /// Checks if k-th element is smaller then it's parent and builds up /// if that yeilds true. /// </summary> /// <param name="k">k-th element.</param> /// <param name="parent">the parent.</param> /// <param name="item">the value of k-th element.</param> /// <returns>boolean value indicating that the heap was build up.</returns> private bool CheckAndBuildUp(int k, int parent, ISchedulableThread item) { if (parent > 0 && item.CompareTo(items[parent]) < 0) { items[k] = items[parent]; items[parent] = item; items[k].SchedulableIndex = k; items[parent].SchedulableIndex = parent; BuildUp(parent); return true; } return false; }
/// <summary> /// Builds the heap down. /// </summary> /// <param name="k">the k-th element to start from.</param> public void BuildDown(int k) { int child = k; for (; 2 * child + 1 < size; k = child) { // local subtree root ISchedulableThread root = items[k]; // left child. child = 2 * k + 1; // if left child is bigger then the right then pick the right. if (child != size - 1 && items[child].CompareTo(items[child + 1]) > 0) child++; // now compare with root if (root.CompareTo(items[child]) > 0) { if (max.CompareTo(items[child]) < 0) max = items[child]; // swamp items[k] = items[child]; items[child] = root; items[k].SchedulableIndex = k; items[child].SchedulableIndex = child; } } }
public ISchedulableThread GetScheduledThread() { ISchedulableThread thread = threadScheduler[0]; return(thread); }