Пример #1
0
PhysicalFrame* findFreePhysicalPage(MMUSim* sim){
  Dllist freeFrames;
  freeFrames = sim->freePhysicalFrames;
  Dllist usedFrames;
  usedFrames = sim->usedPhysicalFrames;
  JRB tree;
  tree = sim->frameTree;
  Dllist nil;
  nil = dll_nil(freeFrames);
  Dllist ffp;
  ffp = dll_first(freeFrames);

  if(ffp != nil){
    PhysicalFrame* freeFrame;
    freeFrame = ffp->val.v;
    dll_delete_node(ffp);
    dll_append(usedFrames, new_jval_v(freeFrame));

    if(sim->rep == 2){ // LRU, sort by time
      jrb_insert_int(tree,freeFrame->lastUsed,new_jval_v(freeFrame));
    } else if(sim->rep == 3){ // LFU, sort by lowCount
      jrb_insert_int(tree,freeFrame->useCount,new_jval_v(freeFrame));
    } else if (sim->rep == 4){ // MFU, sort by highCount
      jrb_insert_int(tree,freeFrame->useCount,new_jval_v(freeFrame));
    }  

    return freeFrame;
  } else {
    return -1;
  }

}
Пример #2
0
MMUProcess* getProcess(MMUSim* sim, int* pid){
  Dllist processList;
  processList = sim->processes;
  Dllist nil;
  nil = dll_nil(processList);
  Dllist s;
  s = dll_first(processList);

  while(s != nil){
    MMUProcess* proc;
    proc = s->val.v;

    if(proc->pid == pid){
      return proc;
    }
    s = s->flink;
  }

  MMUProcess* ps;
  ps = malloc(sizeof(MMUProcess));
  ps->pid = pid;
  ps->stats.pid = pid;
  dll_append(processList, new_jval_v(ps));
  PageTable* pageTable = malloc(sizeof(PageTable));
  PageTableEntry* pageArray = malloc(sim->pageEntries * sizeof(PageTableEntry));
  pageTable->table = pageArray;
  pageTable->size = sim->pageEntries;
  ps->pgtbl = pageTable;

  return ps;
}
Пример #3
0
void *elevator(void *arg){
    Elevator *e = (Elevator *) arg; 
    Dllist item, next, pickup;
    Person *p;
    int direction = 1;
    pickup = new_dllist();

    while(1){

        if(e -> onfloor >= top) direction = -1;
        else if(e -> onfloor <= 1) direction = 1;
        //printf("\tElevator[%i] on floor %i going %s:\n",
        //        e -> id, e -> onfloor, direction == 1 ? "up": "down"); 

        /* pick people up */
        pthread_mutex_lock(lock);

        item = dll_first(people);
        while(!dll_empty(people) && item != dll_nil(people)){
            next = dll_next(item);
            p = (Person *) item -> val.v;

            //printf("\t\tShould I get %s %s going from %i to %i? ",
            //        p -> fname, p -> lname, p -> from, p -> to);

            if(e -> onfloor == p -> from){
                if(p -> to > e -> onfloor && direction == 1 || 
                   p -> to < e -> onfloor && direction == -1){
                    dll_append(pickup, item -> val);
                    dll_delete_node(item);
                    //printf("yes!\n");

                }
                //else printf("no!\n");
            }
            //else printf("no!\n");

            item = next;
        }

        pthread_mutex_unlock(lock);

        item = dll_first(pickup);
        while(!dll_empty(pickup) && item != dll_nil(pickup)){
            next = dll_next(item);
            p = (Person *) item -> val.v;

            if(!e -> door_open) open_door(e);
            pthread_mutex_lock(p -> lock);

            p -> e = e;

            pthread_cond_signal(p -> cond);
            pthread_mutex_lock(e -> lock);
            pthread_mutex_unlock(p -> lock);

            pthread_cond_wait(e -> cond, e -> lock);
            pthread_mutex_unlock(e -> lock);

            dll_delete_node(item);
            item = next;
        }
        if(e -> door_open) close_door(e);

        move_to_floor(e, e -> onfloor + direction);

        /* drop people off */
        item = dll_first(e -> people);
        while(!dll_empty(e -> people) && item != dll_nil(e -> people)){
            next = dll_next(item);
            p = (Person *) item -> val.v;

            if(p -> to == e -> onfloor){
               if(!e -> door_open) open_door(e);
                
               pthread_mutex_lock(p -> lock);
               pthread_cond_signal(p -> cond);
               pthread_mutex_lock(e -> lock);
               pthread_mutex_unlock(p -> lock);

               pthread_cond_wait(e -> cond, e -> lock);
               pthread_mutex_unlock(e -> lock);
            }

            item = next;
        }
        //if(e -> door_open) close_door(e);

    }

    return NULL;
}
Пример #4
0
void runSim(MMUSim* sim, Dllist* traces){
  SimStats* simStats;
  simStats = &(sim->simStats);

  Dllist nil;
  nil = dll_nil(*traces);
  Dllist t;
  t  = dll_first(*traces);

  MMUProcess* currProc;

  while(t != nil){
    Trace* trace;
    trace = t->val.v;

    MMUProcess* proc;
    proc = getProcess(sim, trace->pid);

    if(currProc != proc){
      contextSwitch(sim);
    }
    currProc = proc;

    ProcessStats* pStat;
    pStat = &proc->stats;
    pStat->memoryRef = pStat->memoryRef + 1;
    simStats->memoryRef = simStats->memoryRef + 1;
    
    unsigned int pageNum;
    unsigned int pageOffset;
    getPageNumOffset(sim, trace->address, &pageNum, &pageOffset);
    int op = trace->op;

    if(sim->log){
      char* operation;
      if(op == 1) {operation = "Load from";}
      else if(op == 2) {operation = "Store to";}
      else if(op == 3) {operation = "Instruction fetch from";}
    
      fprintf(stderr, "Process[%u]: %s 0x%x (page: %u, offset: %u)\n",
        trace->pid, operation, trace->address, pageNum, pageOffset);
    }
    // Is the PTE in the TLB?
    PageTableEntry* tlbHit;
retry:
    tlbHit = checkTLB(sim, pageNum);
    simStats->overallLat = simStats->overallLat + sim->tlbLat;
    if((int)tlbHit != -1){ // TLB hit
      if(sim->log) {fprintf(stderr, "\tTLB hit? yes\n");}
      simStats->overallLat = simStats->overallLat + sim->memLat;
      // if write, mark dirty
      if(op == 2){ // Is a write operation?
        tlbHit->dirty = 1;
      }
      if(sim->log) {fprintf(stderr, "\tpage %d in frame %d\n", pageNum, tlbHit->physicalFrame->num);}
      touchFrame(sim, tlbHit->physicalFrame);

    }else{ // TLB miss
      if(sim->log) {fprintf(stderr, "\tTLB hit? no\n");}
      pStat->tlbMisses = pStat->tlbMisses + 1;
      simStats->tlbMisses = simStats->tlbMisses + 1;
      

      // Is the Physical Frame of the PTE present?
      PageTableEntry* pte;
      pte = checkPageTable(sim, proc->pgtbl, pageNum);
      if(pte->present){ // Present bit is set
        if(sim->log) {fprintf(stderr, "\tPage fault? no\n");}
        addPageToTlb(sim, trace->address, pte);
        simStats->overallLat = simStats->overallLat + sim->tlbLat;
        // retry
        goto retry;
      } else { // Physical frame is not loaded (present)
        if(sim->log) {fprintf(stderr, "\tPage fault? yes\n");}
        pStat->pageFaults = pStat->pageFaults + 1;
        simStats->pageFaults = simStats->pageFaults + 1;

        // Is there room?
        PhysicalFrame* pfn;
        pfn = findFreePhysicalPage(sim);
        if(pfn != -1){ // We found a free physical frame
          if(sim->log) {fprintf(stderr, "\tMain memory eviction? no\n");}
         
        } else { // no physical frame was found, need to evict
          if(sim->log) {fprintf(stderr, "\tMain memory eviction? yes\n");}

          // Update evicted PTE
          PhysicalFrame* evPte; // evicted PTE
          PfEvict(sim); // evict a frame based on the chosen policy
          evPte = findFreePhysicalPage(sim); // go and find that frame
          MMUProcess* evProc;
          evProc = getProcess(sim, evPte->pid); // get the process for the evicted frame
          PageTableEntry* evPageTable;
          evPageTable = evProc->pgtbl->table;
          unsigned int evIndex = evPte->pageNum;
          PageTableEntry* evPageTableEntry; // evicted PageTableEntry
          evPageTableEntry = &evPageTable[evIndex];
          evPageTableEntry->present = 0;
          pfn = evPte;

          // clean eviction?
          if(evPageTableEntry->dirty){ // the frame in memory is dirty and needs disk write
            if(sim->log) {fprintf(stderr, "\tProcess %d page %u (dirty) evicted from memory\n", evProc->pid, evPte->pageNum);}

            pStat->dirtyEvict = pStat->dirtyEvict + 1;
            simStats->dirtyEvict = simStats->dirtyEvict + 1;
            // wite to disk + disk access
            simStats->overallLat = simStats->overallLat + sim->diskLat;
            
          } else { // frame is clean
            if(sim->log) {fprintf(stderr, "\tProcess %d page %u (clean) evicted from memory\n", evProc->pid, evPte->pageNum);}

            pStat->cleanEvict = pStat->cleanEvict + 1;
            simStats->cleanEvict = simStats->cleanEvict + 1;
    
          }
          // update PTE
        }
          pte->page = pageNum;
          pte->physicalFrame = pfn;
          simStats->overallLat = simStats->overallLat + sim->diskLat;
          pte->pid = proc->pid;
          pte->present = 1;
          pfn->pid = proc->pid;
          pfn->pageNum = pageNum;
          simStats->overallLat = simStats->overallLat + sim->memLat;

          // update tlb
          addPageToTlb(sim, trace->address, pte);
          simStats->overallLat = simStats->overallLat + sim->tlbLat;
 
          goto retry;
      }
    }
    
    if(sim->log) {fprintf(stderr, "\n");}
    t = t->flink;
  }
  
}
Пример #5
0
void PfEvict(MMUSim* sim){
  Dllist freeFrames;
  Dllist usedFrames;
  freeFrames = sim->freePhysicalFrames;
  usedFrames = sim->usedPhysicalFrames;
  Dllist uNil;
  uNil = dll_nil(usedFrames);
  Dllist uFrame;
  uFrame = dll_first(usedFrames);

  int rep = sim->rep;

  PhysicalFrame* evictFrame;

  if(rep == 1){ // FIFO///////////////////////////////
    // nothing is needed, FIFO happens automatically
    evictFrame = uFrame->val.v;                     
  }//////////////////////////END FIFO/////////////////

  else if(rep == 2){ // LRU///////////////////////////
    
    PhysicalFrame* oldFrame;
    unsigned int oldTime = UINT_MAX;

    PhysicalFrame* frameArray;
    frameArray = sim->physicalFrames;
    PhysicalFrame* currentFrame;

    int i;
    for (i = 0; i < sim->numFrames; i++){
      currentFrame = &frameArray[i];

      if(currentFrame->lastUsed < oldTime){
        oldFrame = currentFrame;
        oldTime = currentFrame->lastUsed;
      }
    }

    evictFrame = oldFrame;

    Dllist* ref;
    ref = evictFrame->listRef;

    uFrame = *ref;

  } ////////////////////END LRU//////////////////////

  else if(rep == 3){ // LFU////////////////////////

    PhysicalFrame* oldFrame;
    int oldUse = INT_MAX;

    PhysicalFrame* frameArray;
    frameArray = sim->physicalFrames;
    PhysicalFrame* currentFrame;

    int i;
    for (i = 0; i < sim->numFrames; i++){
      currentFrame = &frameArray[i];

      if(currentFrame->useCount < oldUse){
        oldFrame = currentFrame;
        oldUse = currentFrame->useCount;
      }
    }

    evictFrame = oldFrame;

    Dllist* ref;
    ref = evictFrame->listRef;

    uFrame = *ref;

  } /////////////////////END LFU//////////////////////

  else if(rep == 4){ // MFU/////////////////////////

    evictFrame = sim->mfuFrame;
    Dllist* ref;
    ref = evictFrame->listRef;

    uFrame = *ref;



  } ////////////////////END MFU//////////////////////

  else{ // RANDOM///////////////////////////////////
    int max = sim->numFrames - 1;
    int randomIndex = ((double) rand() / (((double)RAND_MAX)+1)) * (max+1);

    PhysicalFrame* frameArray;
    frameArray = sim->physicalFrames;
    PhysicalFrame* randomFrame;
    randomFrame = &frameArray[randomIndex];

    evictFrame = randomFrame;

    Dllist* randomRef;
    randomRef = evictFrame->listRef;

    uFrame = *randomRef;
    
  }///////////////// END RANDOM////////////////////

  dll_delete_node(uFrame);
  dll_append(freeFrames, new_jval_v(evictFrame));
  Dllist listItem = dll_last(sim->freePhysicalFrames);
  evictFrame->listRef = listItem;

}