nachos priority scheduler with nonation
来源:互联网 发布:网络通信公司简介 编辑:程序博客网 时间:2024/05/30 20:09
package nachos.threads;import java.util.ArrayList;import java.util.LinkedList;import nachos.machine.*;/** * A scheduler that chooses threads based on their priorities. * * <p> * A priority scheduler associates a priority with each thread. The next thread * to be dequeued is always a thread with priority no less than any other * waiting thread's priority. Like a round-robin scheduler, the thread that is * dequeued is, among all the threads of the same (highest) priority, the * thread that has been waiting longest. * * <p> * Essentially, a priority scheduler gives access in a round-robin fassion to * all the highest-priority threads, and ignores all other threads. This has * the potential to * starve a thread if there's always a thread waiting with higher priority. * * <p> * A priority scheduler must partially solve the priority inversion problem; in * particular, priority must be donated through locks, and through joins. */public class PriorityScheduler extends Scheduler { /** * Allocate a new priority scheduler. */ public PriorityScheduler() { } /** * Allocate a new priority thread queue. * * @paramtransferPriority<tt>true</tt> if this queue should *transfer priority from waiting threads *to the owning thread. * @returna new priority thread queue. */ public ThreadQueue newThreadQueue(boolean transferPriority) {return new PriorityQueue(transferPriority); } public int getPriority(KThread thread) {Lib.assertTrue(Machine.interrupt().disabled()); return getThreadState(thread).getPriority(); } public int getEffectivePriority(KThread thread) {Lib.assertTrue(Machine.interrupt().disabled()); return getThreadState(thread).getEffectivePriority(); } public void setPriority(KThread thread, int priority) {Lib.assertTrue(Machine.interrupt().disabled()); Lib.assertTrue(priority >= priorityMinimum && priority <= priorityMaximum);getThreadState(thread).setPriority(priority); } public boolean increasePriority() {boolean intStatus = Machine.interrupt().disable(); KThread thread = KThread.currentThread();int priority = getPriority(thread);if (priority == priorityMaximum) return false;setPriority(thread, priority+1);Machine.interrupt().restore(intStatus);return true; } public boolean decreasePriority() {boolean intStatus = Machine.interrupt().disable(); KThread thread = KThread.currentThread();int priority = getPriority(thread);if (priority == priorityMinimum) return false;setPriority(thread, priority-1);Machine.interrupt().restore(intStatus);return true; } /** * The default priority for a new thread. Do not change this value. */ public static final int priorityDefault = 1; /** * The minimum priority that a thread can have. Do not change this value. */ public static final int priorityMinimum = 0; /** * The maximum priority that a thread can have. Do not change this value. */ public static final int priorityMaximum = 7; /** * Return the scheduling state of the specified thread. * * @paramthreadthe thread whose scheduling state to return. * @returnthe scheduling state of the specified thread. */ public ThreadState getThreadState(KThread thread) {if (thread.schedulingState == null) thread.schedulingState = new ThreadState(thread);return (ThreadState) thread.schedulingState; } /** * A <tt>ThreadQueue</tt> that sorts threads by priority. */ protected class PriorityQueue extends ThreadQueue { /** The List which acts like a max heap/priority queue*/ public ArrayList<KThread> heap = new ArrayList<KThread>(); public KThread lockOwner;PriorityQueue(boolean transferPriority) { this.transferPriority = transferPriority;}public void waitForAccess(KThread thread) { Lib.assertTrue(Machine.interrupt().disabled()); getThreadState(thread).waitForAccess(this);}public void acquire(KThread thread) { Lib.assertTrue(Machine.interrupt().disabled()); getThreadState(thread).acquire(this);}public void add(KThread kt){heap.add(kt);siftUp();}private void siftDown(){if (heap.size() <=1)return;int left,right;int me=0;int size=heap.size();int max;ThreadState leftTS, rightTS, myTS;myTS=getThreadState(heap.get(me));while(true){max=me;left=(me+1)*2-1;if (left<size){leftTS=getThreadState(heap.get(left));if(leftTS.getEffectivePriority() > myTS.getEffectivePriority())max=left;}else return;right=(me+1)*2;if(right<size){rightTS=getThreadState(heap.get(right));if (rightTS.getEffectivePriority() > myTS.getEffectivePriority()&& rightTS.getEffectivePriority() > leftTS.getEffectivePriority()){max=right;}}if (max==me)return;else{ThreadState childTS = getThreadState(heap.get(max));if (myTS.getEffectivePriority() == childTS.getEffectivePriority() &&myTS.thread.timeAddedToWaitQ > childTS.thread.timeAddedToWaitQ){swap(me,max);me = max;}else{if (myTS.getEffectivePriority() < childTS.getEffectivePriority()){swap(me,max);me = max;}else{break;}}swap(me,max);}}}private void siftUp(){if (heap.size() <=1)return;int me = heap.size()-1;ThreadState myTS, parentTS;while(me!=0){int parent=(me-1)/2;myTS=getThreadState(heap.get(me));parentTS=getThreadState(heap.get(parent));if (myTS.getEffectivePriority() == parentTS.getEffectivePriority() &&myTS.thread.timeAddedToWaitQ < parentTS.thread.timeAddedToWaitQ){swap(me,parent);me = parent;}else{if (myTS.getEffectivePriority() > parentTS.getEffectivePriority()){swap(me,parent);me = parent;}else{break;}}}}private void siftUp(int siftIndex){if (heap.size() <=1)return;int me = siftIndex;ThreadState myTS, parentTS;while(me!=0){int parent=(me-1)/2;myTS=getThreadState(heap.get(me)); parentTS=getThreadState(heap.get(parent));if (myTS.getEffectivePriority() == parentTS.getEffectivePriority() &&myTS.thread.timeAddedToWaitQ < parentTS.thread.timeAddedToWaitQ){swap(me,parent);me = parent;}else{if (myTS.getEffectivePriority() > parentTS.getEffectivePriority()){swap(me,parent);me = parent;}else{break;}}}}public void sort(){for (int i =0;i<heap.size();i++){siftUp(i);}}private void swap(int a, int b){ KThread temp = heap.get(a); heap.set(a, heap.get(b)); heap.set(b, temp);}private KThread dequeue(){if (heap.size()==0 || heap.get(0)==null) return null;swap(0,heap.size()-1);KThread returnThread=heap.get(heap.size()-1);heap.remove(heap.size()-1);siftDown();return returnThread;}private KThread peek(){return heap.get(0);}public KThread nextThread() { Lib.assertTrue(Machine.interrupt().disabled()); KThread t = this.dequeue(); if(t!= null){ ThreadState ts = getThreadState(t); ts.waitIn = null; ts.donatedPriority = 0; } return t; }/** * Return the next thread that <tt>nextThread()</tt> would return, * without modifying the state of this queue. * * @returnthe next thread that <tt>nextThread()</tt> would *return. */protected ThreadState pickNextThread() { return getThreadState(this.peek());}public void print() { Lib.assertTrue(Machine.interrupt().disabled()); // implement me (if you want) }/** * <tt>true</tt> if this queue should transfer priority from waiting * threads to the owning thread. */public boolean transferPriority; } /** * The scheduling state of a thread. This should include the thread's * priority, its effective priority, any objects it owns, and the queue * it's waiting for, if any. * * @seenachos.threads.KThread#schedulingState */ protected class ThreadState {/** * Allocate a new <tt>ThreadState</tt> object and associate it with the * specified thread. * * @paramthreadthe thread this state belongs to. */public ThreadState(KThread thread) { this.thread = thread; setPriority(priorityDefault);}/** * Return the priority of the associated thread. * * @returnthe priority of the associated thread. */public int getPriority() { return priority;}/** * Return the effective priority of the associated thread. * * @returnthe effective priority of the associated thread. */public int getEffectivePriority() { if (priority >=donatedPriority) return priority;else return donatedPriority;}/** * Set the priority of the associated thread to the specified value. * * @paramprioritythe new priority. */public void setPriority(int priority) { if (this.priority == priority)return; if(waitIn != null && waitIn.transferPriority)computeDonations(thread); this.priority = priority; if (waitIn!=null) { if(!waitIn.heap.isEmpty()) { waitIn.sort(); } } }/** * Called when <tt>waitForAccess(thread)</tt> (where <tt>thread</tt> is * the associated thread) is invoked on the specified priority queue. * The associated thread is therefore waiting for access to the * resource guarded by <tt>waitQueue</tt>. This method is only called * if the associated thread cannot immediately obtain access. * * @paramwaitQueuethe queue that the associated thread is *now waiting on. * * @seenachos.threads.ThreadQueue#waitForAccess */public void waitForAccess(PriorityQueue waitQueue) {thread.timeAddedToWaitQ = Machine.timer().getTime();waitQueue.add(thread);this.waitIn=waitQueue;//System.out.println("Waiting Thread = " + thread.getName());if(waitQueue.transferPriority)computeDonations(thread);}/** * Called when the associated thread has acquired access to whatever is * guarded by <tt>waitQueue</tt>. This can occur either as a result of * <tt>acquire(thread)</tt> being invoked on <tt>waitQueue</tt> (where * <tt>thread</tt> is the associated thread), or as a result of * <tt>nextThread()</tt> being invoked on <tt>waitQueue</tt>. * * @seenachos.threads.ThreadQueue#acquire * @seenachos.threads.ThreadQueue#nextThread */public void acquire(PriorityQueue waitQueue) {waitQueue.lockOwner=this.thread;//System.out.println("Got Access: " + thread.getName());}public void computeDonations(KThread t) {ThreadState ts=getThreadState(t);//current thread state we're looking atLinkedList<ThreadState> seenStates = new LinkedList<ThreadState>();while(!seenStates.contains(ts)){seenStates.add(ts);ThreadState lo = ts;if(ts.thread.joiningThread != null) //do join donation{lo = getThreadState(ts.thread.joiningThread);//lock ownerif(lo == ts) break;else if (ts.getEffectivePriority() > lo.getEffectivePriority()){lo.priority = ts.getEffectivePriority();if (lo.waitIn!=null)lo.waitIn.sort();}}else if(ts.waitIn != null && ts.waitIn.transferPriority && ts.waitIn.lockOwner != null){ //wait queue donationlo = getThreadState(ts.waitIn.lockOwner);//lock ownerif(lo == ts) break;else if (ts.getEffectivePriority() > lo.getEffectivePriority()){lo.donatedPriority = ts.getEffectivePriority();if (lo.waitIn!=null)lo.waitIn.sort();}}ts = lo;}}/** The thread with which this object is associated. */ protected KThread thread;/** The priority of the associated thread. */protected int priority;public PriorityQueue waitIn;public int donatedPriority=0; }}
0 0
- nachos priority scheduler with nonation
- nachos-java Task1.5 Priority Scheduling
- Dijkstra with priority queue
- Dijkstra with priority queue
- heap with priority queues
- Priority
- UCB CS162:operating system In Java with NACHOS Lesson 1
- Cool Stuff with Delphi #13 -- Macro Scheduler
- Play with RadScheduler1_TimeSlotCreated Event in Telerik Scheduler
- scheduler
- Scheduler
- nachos资料
- nachos 学习
- Nachos随记
- priority queues
- android:priority
- priority inversion
- init_priority (priority)
- 关于两列布局和三列布局
- 第一篇博客
- Customers Who Never Order
- HDU_1251_统计难题(字典树)
- The Most Simple Introduction to Hypothesis Testing
- nachos priority scheduler with nonation
- power of the test
- Is the “*apply” family really not vectorized?
- POJ_2513_Colored Sticks(欧拉路+字典树)
- How to distinguish between strings in heap or literals?
- 深入理解内存地址
- Remove element
- java 多线程学习笔记之 线程互斥
- ******************** C语言的基础 ********************