Unit1.~cpp
上传用户:z6200320
上传日期:2013-04-04
资源大小:352k
文件大小:6k
源码类别:

操作系统开发

开发平台:

C++ Builder

  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "Unit1.h"
  5. //---------------------------------------------------------------------------
  6. #pragma package(smart_init)
  7. #pragma resource "*.dfm"
  8. TForm1 *Form1;
  9. //---------------------------------------------------------------------------
  10. __fastcall TForm1::TForm1(TComponent* Owner)
  11. : TForm(Owner)
  12. {
  13. }
  14. //---------------------------------------------------------------------------
  15. const PAGES = 5;
  16. const INSTRUCTIONS = 50;
  17. const PAGE_SIZE = 10;
  18. struct PAGE_TABLE
  19. {       
  20.     int pNum; //页号
  21.     int mNum; //物理块号
  22. bool flag; //状态位,用于批示该页是否已调入内存
  23.     int aNum; //访问字段,用于记录本页被访问的次数
  24.     bool modify; //修改位,表示该页在调入内存后是否被修改过
  25.     int address; //物理地址    
  26. } page_table[PAGES];
  27. #define MAXQSIZE 5 //最大队列长度,即最大的内存块数加1
  28. typedef struct
  29. {
  30. int *base; //初始化的动态分配存储空间
  31.     int front; //头指针,若队列不空,指向队列头元素
  32.     int rear; //尾指针,若队列不空,指向队列尾元素的下一个位置
  33. }SqQueue;
  34. SqQueue Q;
  35. struct INSTRUCTION
  36. {
  37. int pNum; //所在页的页号
  38.     int pAddress; //页内地址
  39. }ins[INSTRUCTIONS];
  40. int lack = 0;
  41. //---------------------------------------------------------------------------
  42. //初始化队列,构造一个空的队列Q
  43. bool InitQueue(SqQueue &Q)
  44. {
  45. Q.base = (int *) malloc (MAXQSIZE * sizeof(int));
  46.     if(!Q.base) return false;
  47.     Q.front = Q.rear = 0;
  48.     return true;
  49. }
  50. //---------------------------------------------------------------------------
  51. //插入元素e为Q的新的队尾元素
  52. bool EnQueue(SqQueue &Q,int e)
  53. {
  54. if((Q.rear + 1) % MAXQSIZE == Q.front) return false;
  55. Q.base[Q.rear] = e;
  56.     Q.rear = (Q.rear + 1) % MAXQSIZE;
  57.     return true;
  58. }
  59. //---------------------------------------------------------------------------
  60. //若队列不空则删除Q的队头元素,用e返回其值
  61. bool DeQueue(SqQueue &Q,int &e)
  62. {
  63. if(Q.front == Q.rear) return false;
  64.     e = Q.base[Q.front];
  65.     Q.front = (Q.front + 1) % MAXQSIZE;
  66.     return true;
  67. }
  68. //---------------------------------------------------------------------------
  69. void Display(int i,int address)
  70. {
  71. Form1->Memo1->Lines->Add("指令" + IntToStr(i) + "t的物理地址为: 0x" + IntToHex(address,8));
  72. }
  73. //---------------------------------------------------------------------------
  74. void run(int a,int m)
  75. {
  76. int pNum,address = 0,e = 0;
  77.     pNum = ins[m].pNum;
  78. if(pNum >= PAGES || pNum < 0)
  79.     {
  80.      MessageBox(NULL,"内存地址越界!","警告",false);
  81.         return;
  82.     }
  83.     //页面已在内存中
  84.     if(page_table[pNum].flag == 1)
  85.     {
  86.      //如果选择的是LRU算法
  87.      if(a == 1)
  88.         {
  89.          int ar[MAXQSIZE] = {-1,-1,-1,-1,-1};
  90.             int last = 0;
  91.             //以下两个for循环实现了将最久未使用的项移到队头
  92.          for(int i = 0;i < MAXQSIZE && Q.front != Q.rear;i++)
  93.             {//将队列的元素转存到数组,同时找到当前所用到的页面的页号
  94.              DeQueue(Q,e);
  95.                 ar[i] = e;
  96.                 if(e == pNum) last = i;
  97.             }
  98.             for(int i = 0;ar[i] != -1;i++)
  99.             {//将数组元素重新按原来顺序放回队列,除了当前所用的页面
  100.              if(i != last) 
  101.                 {
  102.                  EnQueue(Q,ar[i]);
  103.                     ar[i] = -1;
  104.                 }
  105.             }
  106.             EnQueue(Q,ar[last]);//将当前所用页面插入队列尾部
  107.         }
  108.         page_table[pNum].flag = 1;
  109.         page_table[pNum].aNum++;
  110.         //地址转换,物理块号的后16位接页内地址
  111.         address = (page_table[pNum].mNum << 16) + ins[m].pAddress;
  112.         //显示指令的物理地址
  113.         Display(m,address);
  114.     }
  115.     //页面不在内存,缺页中断
  116.     else
  117.     {
  118.      Form1->Memo1->Lines->Add("缺页中断,请求调入页面:" + IntToStr(pNum));
  119.         lack++;//缺页数加1
  120.         //队列不满,则直接插入队列
  121.         if((Q.rear + 1) % MAXQSIZE != Q.front) EnQueue(Q,pNum);
  122.         else
  123.         {
  124.          DeQueue(Q,e);
  125.             page_table[e].flag = 0;
  126.             EnQueue(Q,pNum);
  127.         }
  128.         page_table[pNum].flag = 1;
  129.         page_table[pNum].aNum++;
  130.         address = (page_table[pNum].mNum << 16) + ins[m].pAddress;
  131.         Display(m,address);
  132.     }
  133. }
  134. //---------------------------------------------------------------------------
  135.  
  136. void __fastcall TForm1::Btn_RunClick(TObject *Sender)
  137. {
  138. int a,m,len,array[INSTRUCTIONS],ins_array[INSTRUCTIONS];
  139.     len = INSTRUCTIONS;
  140.     if(FIFO->Checked) a = 0;
  141.     else if(LRU->Checked) a = 1;
  142.     //初始化页表
  143.     for(int i = 0;i < PAGES;i++)
  144.     {
  145.         page_table[i].pNum = i;
  146.      for(int j = 0;j < PAGE_SIZE;j++)
  147.         {
  148.          ins[i * 10 + j].pNum = page_table[i].pNum;
  149.             ins[i * 10 + j].pAddress = + j;
  150.         }
  151.         page_table[i].mNum = i;
  152.         page_table[i].flag = 0;
  153.         page_table[i].aNum = 0;
  154.         page_table[i].modify = 0;
  155.         page_table[i].address = i;
  156.     }
  157.     InitQueue(Q);
  158.     srand((unsigned)time(NULL));//产生随机数的种子
  159.     //以下两个for循环用于产生指令访问的随机序列,存入数组ins_array[]
  160.     for(int i = 0;i < INSTRUCTIONS;i++)
  161.     {
  162.      array[i] = i;
  163.     }
  164.     for(int n = 0;n < INSTRUCTIONS;n++)
  165.     {
  166.      if(n == 0) m = random(len);
  167.         else if(n%2 == 0) 
  168.         {
  169.          if(n/2%2 == 1)m = random(m);
  170.             else m = len - random(len + 1 - m);
  171.         }
  172.         if(m == len) m = 0;
  173.         ins_array[n] = array[m];
  174.         for(int i = m;i < len;i++)
  175.         {
  176.          array[i] = array[i + 1];
  177.         }
  178.         len--;
  179.     }
  180.     free(array);
  181.     //执行指令序列
  182.     for(int i = 0;i < INSTRUCTIONS;i++)
  183.     {
  184.      run(a,ins_array[i]);
  185.     }
  186.     free(ins_array);
  187.     Form1->Memo1->Lines->Add("缺页率:" + FloatToStr((float)lack/(float)PAGES));
  188. }
  189. //---------------------------------------------------------------------------