/*
 * Lists of physical pages, in the kernel.
 * Every physical page is on exactly one of these lists.
 * Modeled on 4.4 BSD UNIX.
 */
page_list wired;    /* kernel is using these pages, can't be freed. */
page_list active;   /* recently used, rough LRU order. */
page_list inactive; /* possibly not recently used, rough LRU order. */
page_list free;     /* not recently used. clean. rough LRU order. */

/*
 * Pageout daemon pseudo-code.
 * Runs in the background as a thread inside the kernel.
 */
pageout_daemon(){
  while(1){
    while(inactive list is too short){
      pop a page from the head of the active list.
      If reference bit set, clear it, move to tail of active list.
      Otherwise, move to tail of inactive list.
    }
    while(free list is too short){
      pop a page from the head of the inactive list.
      If reference bit set, clear it, move to tail of active list.
      Otherwise,
        If dirty, queue write and move to tail of active list.
        Otherwise, move to tail of free list.
          And remove from relevant vm object.
    }
    sleep for a while, or until vm_page_alloc sees free list too short.
  }
}

/*
 * Physical page allocation pseudocode.
 * Called in the page fault hander to find a physical page of
 * memory that a process can use.
 */
vm_page_alloc() {
  if(free list is short)
    wake up pageout daemon.
  take a page from the free list.
}

