Nachos课程设计Task1.3

要求:

需要完成Alarm,实现waitUntil(longx )方法。一个 线程调用waitUntil将挂起自己的执行,直到时间变为now+x。线程在唤醒后将它们放入到等待队列中。不生成其他的线程实现waitUntil方 法,修 改waitUntil方 法 和定 时 器 中 断 处 理 程 序 。waitUntil不限于一个线程,任何数目的线程均可调用它,每次一个线程挂起。现在的代码只是让程序能运行,并没有真正实现该功能。挂起该进程,就必须挂起到一个地方,能够根据时间再次唤醒该进程。在这里用信号量的方式来实现唤醒功能(当然也可以用条件变量)。Alarm构 造 函数 调 用setInterruptHandler(Runnablehandler)timerInterrupt()方法注册为时钟回调方法,即时钟每次tick时调用。初始化一张线程等待表,线程等待表存放一种数据结构,该数据结构包含正在等待的线程的ID及需要被唤醒的时间以及信号量。Alarm要求实现waitUntil(longx)方法,该方法用于等待一定的时间将线程唤醒,等待时间长度为x,Nachos的时间采用模拟的tick计数,所以实现时应使用Machine.timer().getTime()方法获取当前时间加上等待的时间长度表示线程被唤起的时间点,加入到线程等待表中,并调KThread.sleep()挂起当前线程。timerInterrupt()方法检查线程等待表,将其中超时的线程唤醒,这里可以用优先队列存储表,优先队列将按超时时间排序,检查时便不需要遍历整张表,提高效率。

具体实现如下:

先构建一个数据结构,该数据结构包含一个线程,被唤醒的时间,信号量(写在alarm.java)

	// 该结构是由一个当前线程,等待的时间,相应的条件变量组成;
	private class WaitItem {
		KThread thread;
		long waittime;
		// Condition2 condition;
		Semaphore semaphore;

		public WaitItem(KThread thread, long waittime, Semaphore semaphore) {
			this.thread = thread;
			this.waittime = waittime;
			this.semaphore = semaphore;
		}

	}


初始化一个等待队列来存放这些该结构,在这里我们用
<span style="white-space:pre">	</span>// 等在alarm上的线程
	public static  LinkedList<WaitItem> alarmqueue = new LinkedList<WaitItem>();


 当一个线程等待的时候,则将该线程放入等待队列中睡眠,则 
waituntil函数如下: 

	public void waitUntil(long x) {
		// for now, cheat just to get something working (busy waiting is bad)

		long wakeTime = Machine.timer().getTime() + x;
		Semaphore semaphore = new Semaphore(0);
		WaitItem waitItem = new WaitItem(KThread.currentThread(), wakeTime,
				semaphore);
		alarmqueue.add(waitItem);
		semaphore.P();

	}



Alarm构 造 函数 调 用 setInterruptHandler(Runnablehandler)timerInterrupt()方法注册为时钟回调方法 ,即时钟每次 tick时调用。我们利用时钟回调来检查该线程是都到达被唤醒的时间,即没 500ticks检查一次,如果没有到,则继续 sleep,如果时间到了或者是超过了则唤醒。故

timerInterrupt()函数实现如下:

public void timerInterrupt() {
		for (Iterator x = alarmqueue.iterator(); x.hasNext();) {
			WaitItem item = (WaitItem) x.next();
		//	System.out.println(item.toString());
			if (item.waittime <= Machine.timer().getTime()) {
				item.semaphore.V();
				x.remove();
			}
		}
		
	}

这里重新写了他的测试方式,(测试方法写在KThread.java),并且ping线程在循环中使用Alarm进行延迟,同时测试了AlarmwaitUntil方法。然后在ThreadedKernel 里调用KThread.AlarmTest(); 进行测试

private static class AlarmPingTest implements Runnable {
		AlarmPingTest(SynchList ping, SynchList pong) {
			this.ping = ping;
			this.pong = pong;
		}

		public void run() {
    	for (int i=0; i<10; i++) {
    	System.out.println("ping remove " +i);
    	Object o = ping.removeFirst();
    	System.out.println("ping remove done " + o);
    	System.out.println("pong add " + i);
    	pong.add(o);
    	System.out.println("pong add done "+ i);}
    	}

		private SynchList ping;
		private SynchList pong;
	}
 /**
  * Alarm_waituntil 测试
  * @author dan
  * 
  */
	public static void AlarmTest() {
		SynchList ping = new SynchList();
		SynchList pong = new SynchList();
		new KThread(new AlarmPingTest(ping, pong)).setName("alarmtest").fork();
		for (int i = 0; i < 5; i++) {
			Integer o = new Integer(i);
			System.out.println("ping add " + i);
			ping.add(o);
			ping.add(o);
			System.out.println("ping add done " + i);
			// 使用 Alarm 的 waitUntil 方法延迟
			new Alarm().waitUntil(10000000);
			System.out.println("alarmtest wake");
			System.out.println("pong remove " + i);
			// Lib.assertTrue(pong.removeFirst() == o);
			pong.removeFirst();
			pong.removeFirst();
			System.out.println("pong remove done " + i);
		}
	}



对应输出:pingadd 0

pingadd done 0

pingremove 0

pingremove done 0

pongadd 0

pongadd done 0

pingremove 1

pingremove done 1

pongadd 1

pongadd done 1

pingremove 2

thread0wake

pongremove 0

pongremove done 0

pingadd 1

pingadd done 1

pingremove done 2

pongadd 2

pongadd done 2

pingremove 3

pingremove done 3

pongadd 3

pongadd done 3

pingremove 4

thread0wake

pongremove 1

pongremove done 1

pingadd 2

pingadd done 2

pingremove done 4

pongadd 4

pongadd done 4

pingremove 5

pingremove done 5

pongadd 5pong add done 5

pingremove 6

thread0wake

pongremove 2

pongremove done 2

pingadd 3

pingadd done 3

pingremove done 6

pongadd 6

pongadd done 6

pingremove 7

pingremove done 7

pongadd 7

pongadd done 7

pingremove 8

thread0wake

pongremove 3

pongremove done 3

pingadd 4

pingadd done 4

pingremove done 8

pongadd 8

pongadd done 8

pingremove 9

pingremove done 9

pongadd 9

pongadd done 9

thread0wake

pongremove 4

pongremove done 4




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值