示例#1
0
struct cache_line *get_line_to_use(struct set *set_to_observe) {
/*
    Main function for choosing a line that will be used for storing
    another portion of data
*/
    int number_of_lines = set_to_observe->number_of_lines;
    int *line_age = calloc(number_of_lines, sizeof(int));
    int i;
    struct cache_line *current_line;
    struct cache_line *result_line;
    for (i = 0; i < number_of_lines; i++) {
        current_line = &(set_to_observe->lines[i]);
        if (is_usable(current_line)) {
            return current_line;
        }
        line_age[i] = current_line->age;
    }
    /* If we are here no usable line was found.
    We will be using the "LRU" cache policy. */
    result_line = get_lru_line(set_to_observe->lines, number_of_lines, line_age);
    free(line_age);
    return result_line;
}
/**
 * The initialization function for the allocation table AT.
 * It contains two major parts:
 * 1. Calculate the actual physical memory of the machine, and sets the number of physical pages (NUM_PAGES).
 * 2. Initializes the physical allocation table (AT) implemented in MATIntro layer, based on the
 *    information available in the physical memory map table.
 *    Review import.h in the current directory for the list of avaiable getter and setter functions.
 */
void
pmem_init(unsigned int mbi_addr)
{
  unsigned int nps;

  // TODO: Define your local variables here.
  // number of rows
  unsigned int rows;
  unsigned int h_addr;
  unsigned int i;
  unsigned int first_row, tmp_row;
  //Calls the lower layer initializatin primitives.
  //The parameter mbi_addr shell not be used in the further code.
	devinit(mbi_addr);

  /**
   * Calculate the number of actual number of avaiable physical pages and store it into the local varaible nps.
   * Hint: Think of it as the highest address possible in the ranges of the memory map table,
   *       divided by the page size.
   */
  // TODO
  rows = get_size();
  h_addr = get_mms(rows - 1) + get_mml(rows - 1);
  dprintf("h_addr: %u\n", h_addr);
  nps = h_addr / PAGESIZE;
	set_nps(nps); // Setting the value computed above to NUM_PAGES.

  /**
   * Initialization of the physical allocation table (AT).
   *
   * In CertiKOS, the entire addresses < VM_USERLO or >= VM_USERHI are reserved by the kernel.
   * That corresponds to the physical pages from 0 to VM_USERLO_PI-1, and from VM_USERHI_PI to NUM_PAGES-1.
   * The rest of pages that correspond to addresses [VM_USERLO, VM_USERHI), can be used freely ONLY IF
   * the entire page falls into one of the ranges in the memory map table with the permission marked as usable.
   *
   * Hint:
   * 1. You have to initialize AT for all the page indices from 0 to NPS - 1.
   * 2. For the pages that are reserved by the kernel, simply set its permission to 1.
   *    Recall that the setter at_set_perm also marks the page as unallocated. 
   *    Thus, you don't have to call another function to set the allocation flag.
   * 3. For the rest of the pages, explore the memory map table to set its permission accordingly.
   *    The permission should be set to 2 only if there is a range containing the entire page that
   *    is marked as available in the memory map table. O.w., it should be set to 0.
   *    Note that the ranges in the memory map are not aligned by pages.
   *    So it may be possible that for some pages, only part of the addresses are in the ranges.
   *    Currently, we do not utilize partial pages, so in that case, you should consider those pages as unavailble.
   * 4. Every page in the allocation table shold be initialized.
   *    But the ranges in the momory map table may not cover the entire available address space.
   *    That means there may be some gaps between the ranges.
   *    You should still set the permission of those pages in allocation table to 0.
   */
  // TODO
  for (i = 0; i < VM_USERLO_PI; i++) {
      // check if one page occupies two rows
     at_set_perm(i, 1);
  }
  for (first_row = 0; first_row < rows - 1; first_row++) {
     if (get_mms(first_row) + get_mml(first_row) < i * PAGESIZE && get_mms(first_row + 1) < (i + 1) * PAGESIZE) {
        first_row ++;
        break;
     }
  }
  for (i = VM_USERLO_PI; i < VM_USERHI_PI; i++) {
     if (i * PAGESIZE <= get_mms(first_row) + get_mml(first_row) && (i + 1) * PAGESIZE > get_mms(first_row) + get_mml(first_row)) {
        first_row ++ ;
        at_set_perm(i, 0);
     } else if (is_usable(i)) {
        at_set_perm(i, 2);
     } else {
        at_set_perm(i, 0);
     }
  }
  for (i = VM_USERHI; i < nps; i++) {
     at_set_perm(i, 1);
  }
  
}