Nachos(2)

#1

코드

selfTest2()

public static void selfTest2() {
	Lib.debug(dbgThread, "Enter KThread.selfTest2");

	int timeslice;
	int numberOfThreads;
	int burstTime1;
	int burstTime2;

	String fileName = "input";
	try {
		FileReader fileReader = new FileReader(fileName);
		BufferedReader bufferedReader = new BufferedReader(fileReader);

		String line = bufferedReader.readLine();
		timeslice = Integer.parseInt(line);

		line = bufferedReader.readLine();
		numberOfThreads = Integer.parseInt(line);

		line = bufferedReader.readLine();
		burstTime1 = Integer.parseInt(line);

		line = bufferedReader.readLine();
		burstTime2= Integer.parseInt(line);

		bufferedReader.close();

		new KThread(new SimpleThread(burstTime1, timeslice))
		.setName("forked thread 1").fork();
		new KThread(new SimpleThread(burstTime2, timeslice))
		.setName("forked thread 2").fork();
		new mainThread().run();
		yield();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

SimpleThread

private static class SimpleThread implements Runnable {
	SimpleThread(int burst_time, int timeslice) {
		this.burst_time = burst_time;
		this.timeslice = timeslice;
	}

	public void run() {
		int remaining_time = burst_time;
		long current_tick;
		while(remaining_time > 0) {
			while(timeslice > 0 && remaining_time > 0) {
				current_tick = Machine.timer().getTime();
				remaining_time--;
				timeslice--;
				System.out.println(current_tick 
				+ " running:" + currentThread.getName()
					+ ", remaining time: " + remaining_time);
				Machine.interrupt().tick(false);
			}
			currentThread.yield();
			timeslice = 2;
		}
	}
	private int burst_time;
	private int timeslice;
}

실행 결과

result01

#2

Abstract Class Scheduler


Schdeuler()

_newThreadQueue(boolean transferPriority)

getPriority(KThread thread)

getPriority()

getEffectivePriority(KThread thread)

getEffectivePriority()

setPriority(KThread thread, int priority)

setPriority(int priority)

increasePriority(), decreasePriority()

PriorityScheduler


newThreadQueue(boolean transferPriority)

public ThreadQueue newThreadQueue(boolean transferPriority) {
	return new PriorityQueue(transferPriority);
}

getPriority(KThread thread)

public int getPriority(KThread thread) {
	Lib.assertTrue(Machine.interrupt().disabled());
	
	return getThreadState(thread).getPriority();
}

getEffectivePriority(KThread thread)

public int getEffectivePriority(KThread thread) {
	Lib.assertTrue(Machine.interrupt().disabled());
	
	return getThreadState(thread).getEffectivePriority();
}

setPriority(KThread thread, int priority)

public void setPriority(KThread thread, int priority) {
	Lib.assertTrue(Machine.interrupt().disabled());
	Lib.assertTrue(priority >= priorityMinimum &&
	priority <= priorityMaximum);
	
	getThreadState(thread).setPriority(priority);
}

increasePriority()

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;
}

decreasePriority()

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;
}

getThreadState(KThread thread)

protected ThreadState getThreadState(KThread thread) {
	if (thread.schedulingState == null)
		thread.schedulingState = new ThreadState(thread);
	
	return (ThreadState) thread.schedulingState;
}

PriorityQueue


Member Variables

protected final List<ThreadState> threadsWaiting;
protected ThreadState resourceHolder = null;
protected int effectivePriority = priorityMinimum;
protected boolean priorityChange;
public boolean transferPriority;

PriorityQueue(boolean transferPriority)

PriorityQueue(boolean transferPriority) {
	this.transferPriority = transferPriority;
	this.threadsWaiting = new LinkedList<ThreadState>();
}

waitForAccess(KThread thread)

public void waitForAccess(KThread thread) {
	Lib.assertTrue(Machine.interrupt().disabled());
	final ThreadState ts = getThreadState(thread);
	this.threadsWaiting.add(ts);
	ts.waitForAccess(this);
}

acquire(KThread thread)

public void acquire(KThread thread) {
	Lib.assertTrue(Machine.interrupt().disabled());
	
	final ThreadState ts = getThreadState(thread);
	if(this.resourceHolder != null) {
		this.resourceHolder.release(this);
	}
	this.resourceHolder = ts;
	ts.acquire(this);
}

nextThread()

public KThread nextThread() {
	Lib.assertTrue(Machine.interrupt().disabled());
	
	final ThreadState nextThread = this.pickNextThread();
	if(nextThread == null) return null;
	this.threadsWaiting.remove(nextThread);
	this.acquire(nextThread.getThread());
	return nextThread.getThread();
}

pickNextThread()

protected ThreadState pickNextThread() {
	int nextPriority = priorityMinimum;
	ThreadState next = null;
	
	for (final ThreadState currThread : this.threadsWaiting) {
		int currPriority = currThread.getEffectivePriority();
		if(next == null || (currPriority > nextPriority)) {	
				next = currThread;
				nextPriority = currPriority;
			}
	}
	return next;
}

getEffectivePriority()

public int getEffectivePriority() {
	if(!this.transferPriority) return priorityMinimum;
	else if(this.priorityChange) {
		this.effectivePriority = priorityMinimum;
		for(final ThreadState curr : this.threadsWaiting) {
			this.effectivePriority =
			Math.max(this.effectivePriority, curr.getEffectivePriority());
		}
		this.priorityChange = false;
	}
	return effectivePriority;
}

invalidateCachedPriority()

private void invalidateCachedPriority() {
	if(!this.transferPriority) return;
	this.priorityChange = true;
	if(this.resourceHolder != null) resourceHolder.invalidateCachedPriority();
}

ThreadState


Member Variables

protected KThread thread;
protected int priority;
protected boolean priorityChange = false;
protected int effectivePriority = priorityMinimum;
protected final List<PriorityQueue> resourcesIHave;
protected final List<PriorityQueue> resourcesIWant;

ThreadState(KThread thread)

public ThreadState(KThread thread) {
	this.thread = thread;
	this.resourcesIHave = new LinkedList<PriorityQueue>();
	this.resourcesIWant = new LinkedList<PriorityQueue>();
	setPriority(priorityDefault);
}

getPriority()

public int getPriority() {
	return priority;
}

getEffectivePriority()

public int getEffectivePriority() {
	if(this.resourcesIHave.isEmpty()) return this.getPriority();
	else if(this.priorityChange) {
		this.effectivePriority = this.getPriority();
		for(final PriorityQueue pq : this.resourcesIHave) {
			this.effectivePriority =
			Math.max(this.effectivePriority, pq. getEffectivePriority());
		}
		this.priorityChange = false;
	}
	return this.effectivePriority;
}

setPriority(int priority)

public void setPriority(int priority) {
	if (this.priority == priority) return;
	this.priority = priority;
	for(final PriorityQueue pq : resourcesIWant) {
		 q.invalidateCachedPriority();
	}
}

waitForAccess(PriorityQueue waitQueue)

public void waitForAccess(PriorityQueue waitQueue) {
	this.resourcesIWant.add(waitQueue);
	this.resourcesIHave.remove(waitQueue);
	waitQueue.invalidateCachedPriority();
}

acquire(PriorityQueue waitQueue)

public void acquire(PriorityQueue waitQueue) {
	this.resourcesIHave.add(waitQueue);	
	this.resourcesIWant.remove(waitQueue);	
	this.invalidateCachedPriority();
}

release(PriorityQueue waitQueue)

public void release(PriorityQueue waitQueue) {
	this.resourcesIHave.remove(waitQueue);
	this.invalidateCachedPriority();
}

getThread()

public KThread getThread() {
	return thread;
}

invalidateCachedPriority()

private void invalidateCachedPriority() {
	if(this.priorityChange) return;
	this.priorityChange = true;
	for(final PriorityQueue pq : this.resourcesIWant) {
		pq.invalidateCachedPriority();
	}
}

reference