《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
5.2 KiB

10 years ago
  1. #include <defs.h>
  2. #include <x86.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <swap.h>
  6. #include <swap_fifo.h>
  7. #include <list.h>
  8. /* [wikipedia]The simplest Page Replacement Algorithm(PRA) is a FIFO algorithm. The first-in, first-out
  9. * page replacement algorithm is a low-overhead algorithm that requires little book-keeping on
  10. * the part of the operating system. The idea is obvious from the name - the operating system
  11. * keeps track of all the pages in memory in a queue, with the most recent arrival at the back,
  12. * and the earliest arrival in front. When a page needs to be replaced, the page at the front
  13. * of the queue (the oldest page) is selected. While FIFO is cheap and intuitive, it performs
  14. * poorly in practical application. Thus, it is rarely used in its unmodified form. This
  15. * algorithm experiences Belady's anomaly.
  16. *
  17. * Details of FIFO PRA
  18. * (1) Prepare: In order to implement FIFO PRA, we should manage all swappable pages, so we can
  19. * link these pages into pra_list_head according the time order. At first you should
  20. * be familiar to the struct list in list.h. struct list is a simple doubly linked list
  21. * implementation. You should know howto USE: list_init, list_add(list_add_after),
  22. * list_add_before, list_del, list_next, list_prev. Another tricky method is to transform
  23. * a general list struct to a special struct (such as struct page). You can find some MACRO:
  24. * le2page (in memlayout.h), (in future labs: le2vma (in vmm.h), le2proc (in proc.h),etc.
  25. */
  26. list_entry_t pra_list_head;
  27. /*
  28. * (2) _fifo_init_mm: init pra_list_head and let mm->sm_priv point to the addr of pra_list_head.
  29. * Now, From the memory control struct mm_struct, we can access FIFO PRA
  30. */
  31. static int
  32. _fifo_init_mm(struct mm_struct *mm)
  33. {
  34. list_init(&pra_list_head);
  35. mm->sm_priv = &pra_list_head;
  36. //cprintf(" mm->sm_priv %x in fifo_init_mm\n",mm->sm_priv);
  37. return 0;
  38. }
  39. /*
  40. * (3)_fifo_map_swappable: According FIFO PRA, we should link the most recent arrival page at the back of pra_list_head qeueue
  41. */
  42. static int
  43. _fifo_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in)
  44. {
  45. list_entry_t *head=(list_entry_t*) mm->sm_priv;
  46. list_entry_t *entry=&(page->pra_page_link);
  47. assert(entry != NULL && head != NULL);
  48. //record the page access situlation
  49. /*LAB3 EXERCISE 2: YOUR CODE*/
  50. //(1)link the most recent arrival page at the back of the pra_list_head qeueue.
  51. list_add(head, entry);
  52. return 0;
  53. }
  54. /*
  55. * (4)_fifo_swap_out_victim: According FIFO PRA, we should unlink the earliest arrival page in front of pra_list_head qeueue,
  56. * then set the addr of addr of this page to ptr_page.
  57. */
  58. static int
  59. _fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick)
  60. {
  61. list_entry_t *head=(list_entry_t*) mm->sm_priv;
  62. assert(head != NULL);
  63. assert(in_tick==0);
  64. /* Select the victim */
  65. /*LAB3 EXERCISE 2: YOUR CODE*/
  66. //(1) unlink the earliest arrival page in front of pra_list_head qeueue
  67. //(2) set the addr of addr of this page to ptr_page
  68. /* Select the tail */
  69. list_entry_t *le = head->prev;
  70. assert(head!=le);
  71. struct Page *p = le2page(le, pra_page_link);
  72. list_del(le);
  73. assert(p !=NULL);
  74. *ptr_page = p;
  75. return 0;
  76. }
  77. static int
  78. _fifo_check_swap(void) {
  79. cprintf("write Virt Page c in fifo_check_swap\n");
  80. *(unsigned char *)0x3000 = 0x0c;
  81. assert(pgfault_num==4);
  82. cprintf("write Virt Page a in fifo_check_swap\n");
  83. *(unsigned char *)0x1000 = 0x0a;
  84. assert(pgfault_num==4);
  85. cprintf("write Virt Page d in fifo_check_swap\n");
  86. *(unsigned char *)0x4000 = 0x0d;
  87. assert(pgfault_num==4);
  88. cprintf("write Virt Page b in fifo_check_swap\n");
  89. *(unsigned char *)0x2000 = 0x0b;
  90. assert(pgfault_num==4);
  91. cprintf("write Virt Page e in fifo_check_swap\n");
  92. *(unsigned char *)0x5000 = 0x0e;
  93. assert(pgfault_num==5);
  94. cprintf("write Virt Page b in fifo_check_swap\n");
  95. *(unsigned char *)0x2000 = 0x0b;
  96. assert(pgfault_num==5);
  97. cprintf("write Virt Page a in fifo_check_swap\n");
  98. *(unsigned char *)0x1000 = 0x0a;
  99. assert(pgfault_num==6);
  100. cprintf("write Virt Page b in fifo_check_swap\n");
  101. *(unsigned char *)0x2000 = 0x0b;
  102. assert(pgfault_num==7);
  103. cprintf("write Virt Page c in fifo_check_swap\n");
  104. *(unsigned char *)0x3000 = 0x0c;
  105. assert(pgfault_num==8);
  106. cprintf("write Virt Page d in fifo_check_swap\n");
  107. *(unsigned char *)0x4000 = 0x0d;
  108. assert(pgfault_num==9);
  109. return 0;
  110. }
  111. static int
  112. _fifo_init(void)
  113. {
  114. return 0;
  115. }
  116. static int
  117. _fifo_set_unswappable(struct mm_struct *mm, uintptr_t addr)
  118. {
  119. return 0;
  120. }
  121. static int
  122. _fifo_tick_event(struct mm_struct *mm)
  123. { return 0; }
  124. struct swap_manager swap_manager_fifo =
  125. {
  126. .name = "fifo swap manager",
  127. .init = &_fifo_init,
  128. .init_mm = &_fifo_init_mm,
  129. .tick_event = &_fifo_tick_event,
  130. .map_swappable = &_fifo_map_swappable,
  131. .set_unswappable = &_fifo_set_unswappable,
  132. .swap_out_victim = &_fifo_swap_out_victim,
  133. .check_swap = &_fifo_check_swap,
  134. };