<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>elevator</title>
</head>

<body>



<p align="left"><span lang="en-ca"><font size="6" color="#FF0000"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
The elevator algorithm</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A. <span lang="en-ca">First</span> Edition</font></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>This is a small demo program to test the algorithm of elevator algorithm which is used in disk for arm moving.</b></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<div align="left">
  <font FACE="TimesNewRomanPSMT">
  <p ALIGN="LEFT"><span lang="en-ca"><b>The problem is a simple: what is the 
  average waiting time or latency time for disk arm to move to</b></span></p>
  <p ALIGN="LEFT"><span lang="en-ca"><b>required track? In the book, it is said 
  1/3 of total track number moving time and I am not sure </b></span></p>
  <p ALIGN="LEFT"><span lang="en-ca"><b>about the number. By elevator algorithm, 
  the disk arm will just move like an elevator to one </b></span></p>
  <p ALIGN="LEFT"><span lang="en-ca"><b>direction until in its front there is no 
  more track to scan or no more task waiting. Then the arm </b></span></p>
  <p ALIGN="LEFT"><span lang="en-ca"><b>change direction. So simple, so easy. 
  However, I am puzzled if I need to &quot;buffer&quot; the incoming </b></span></p>
  <p ALIGN="LEFT"><span lang="en-ca"><b>tasks in a waiting list. I decide to 
  have because disk has a buffer and can only accept a bunch of</b></span></p>
  <p ALIGN="LEFT"><span lang="en-ca"><b>task at one time. (This may not be true. 
  And I will modify this in next edition shortly.)</b></span></p>
  </font>
  <p ALIGN="LEFT">　</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca"><a name="explain"></a>C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <pre><span lang="en-ca"><b><font face="TimesNewRomanPSMT">There is a class called Arm and it has a class object Timer which can tick whenever Arm moves one step. In the</font></b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b><font face="TimesNewRomanPSMT">ticking of Timer, it calculates a possibility to generate new tasks in a &quot;waiting&quot; list. The waiting list will</font></b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b><font face="TimesNewRomanPSMT">be copied into a &quot;working&quot; list if the tasks in &quot;working&quot; list runs out. The rate of generating new tasks is</font></b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b><font face="TimesNewRomanPSMT">a bit of tricky. I presumed the waiting queue is a stable queue such that the rate of leaving tasks is same as</font></b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b><font face="TimesNewRomanPSMT">the rate of incoming tasks. So, I record the period of last searching time and possibility of generating a new</font></b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b><font face="TimesNewRomanPSMT">task will depend on how...(My God! it is wrong and I will change this in next edition.)</font></b></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">E</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre><b><span lang="en-ca">It is a small game and no one would bother to treat them seriously, I presume.</span></b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">F</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>File listing</b></font></span></pre>
</div>
<div align="left" style="width: 898; height: 86">
  <pre><font size="3"><b><span lang="en-ca">1. disk</span>.<span lang="en-ca">cpp(main)</span></b></font></pre>
  <pre><span lang="en-ca"><font size="3" color="#FF0000"><b>file name: naughty</b></font></span><font size="3" color="#FF0000"><b>.<span lang="en-ca">cpp</span></b></font></pre>
  <pre>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;

const int MaxTrackNumber=40;
const int MaxTaskNumber=30;
const int TotalTaskNumber=1600;
const int Average=20;


struct Task
{
	int startTime;
	int track;
	int endTime;
};

Task taskPool[TotalTaskNumber];

class Arm;


class Timer
{
	friend class Arm;
private:
	int working[MaxTrackNumber];
	int waiting[MaxTrackNumber];
	int workingCount;
	int waitingCount;
	int lastPeriod;
	int currPeriod;
	int counter;
	bool possible();
	bool testDir(bool forward, int current);
	int taskIndex;

public:
	void generate();
	Timer();
	int getTime(){return counter;}
	void tick(int curPos);
	void reset();
	void taskTest(bool&amp; forward, int&amp; current);
	bool finished(){return taskIndex==TotalTaskNumber;}
};



class Arm
{
private:
	bool forward;
	int current;
	Timer timer;
public:
	Arm();
	bool step();
	void report();
};


int main()
{
	Arm A;
	srand(time(0));
	while (!A.step())
	{
		//A.report();
	}
	A.report();
	return 0;
}




//timer tick and solve task, generate new task by possibility
void Timer::tick(int curPos)
{
	counter++;
	generate();
	if (working[curPos]!=-1)
	{
		//if (taskPool[working[curPos]].endTime==-1)
		{
			taskPool[working[curPos]].endTime=counter;
			workingCount--;
			working[curPos]=-1;
		}
	}
}

bool Timer::possible()
{
	currPeriod++;
	//waitingCount/currPeriod
	return currPeriod-rand()%lastPeriod&gt;=0;
}

void Timer::generate()
{
	int theTrack;
	if (finished())
	{
		return;
	}
	if (waitingCount&lt;MaxTaskNumber)
	{
		if (possible())//generate
		{
			taskPool[taskIndex].startTime=counter;
			theTrack=rand()%MaxTrackNumber;
			while (working[theTrack]!=-1||waiting[theTrack]!=-1)
			{
				theTrack=rand()%MaxTrackNumber;
			}
			taskPool[taskIndex].track=theTrack;
			taskPool[taskIndex].endTime=-1;//initialize
			waiting[theTrack]=taskIndex;
			waitingCount++;
			taskIndex++;
		}
	}
}

Timer::Timer()
{
	counter=0;
	taskIndex=0;
	lastPeriod=Average;
	currPeriod=0;
	waitingCount=workingCount=0;
	for (int i=0; i&lt;MaxTrackNumber; i++)
	{
		working[i]=waiting[i]=-1;
	}
}

void Timer::reset()
{
	if (workingCount==0)
	{
		for (int i=0; i&lt;MaxTrackNumber; i++)
		{
			working[i]=waiting[i];
			waiting[i]=-1;//clear up
		}
		lastPeriod=currPeriod;
		currPeriod=0;
		workingCount=waitingCount;
		waitingCount=0;//clear up
	}
}


void Timer::taskTest(bool&amp; forward, int&amp; current)
{
	//always to call reset in case working period finished
	reset();
	//first to determine direction
	if (forward)
	{
		//always assume change direction unless...
		forward=false;
		//unless there is something to explore
		
		for (int i=current+1; i&lt;MaxTrackNumber; i++)
		{
			if (working[i]!=-1)
			{
				forward=true;
				break;
			}
		}			
	}
	else
	{
		//always assume change direction
		forward=true;

		for(int i=current-1; i&gt;=0; i--)
		{
			if (working[i]!=-1)
			{
				//unless we find reason for keep going
				forward=false;
				break;
			}
		}	
	}
	//since we setup direction,let's go
	if (forward)
	{
		current++;
	}
	else
	{
		current--;
	}
	tick(current);
}

bool Arm::step()
{
	//it is timer's responsibility to determine forward
	timer.taskTest(forward, current);
	return timer.workingCount==0&amp;&amp;timer.finished()&amp;&amp;timer.waitingCount==0;
	//timer.tick(current);
}
	
Arm::Arm()
{
	current=0;
	forward=true;
	//initialize to have at least one task
	while (timer.waitingCount&lt;1)
	{
		timer.generate();
	}
}

void Arm::report()
{
	long total=0;
	if (timer.finished())
	{
		for (int i=0; i&lt;TotalTaskNumber; i++)
		{
			total+=taskPool[i].endTime-taskPool[i].startTime;
		}
		printf(&quot;total waiting time is %d\n&quot;, total);
		printf(&quot;for total number %d tasks, the average waiting time:\n%d&quot;, 
			TotalTaskNumber, total/TotalTaskNumber);
		printf(&quot;and ratio with number of track is %d/%d=%d\n&quot;, total/TotalTaskNumber, 
			MaxTrackNumber,	total/TotalTaskNumber/MaxTrackNumber);
	}
	else
	{
		printf(&quot;task proceeding no. %d\n&quot;, timer.taskIndex);
	}
}
</pre>
  <pre>

</pre>
  <pre></pre>
  <pre></pre>
  <pre></pre>
</div>
<pre></pre>
<pre></pre>
<pre></pre>
<pre><span lang="en-ca"><font color="#0000FF"><b>The result is like following: And it is not correct!  </b></font></span></pre>

<pre>　</pre>

<pre><span lang="en-ca">total waiting time is 56532
for total number 1600 tasks, the average waiting time:
35and ratio with number of track is 35/40=0
Press any key to continue				</span> <a href="game24.htm"><img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35"> </pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp;</p>

</body>

</html>