/*------------------------------------------------------------------------- * xmunmap - xmunmap *------------------------------------------------------------------------- */ SYSCALL xmunmap(int virtpage ) { bs_map_t *temp_bs,*prev_bs; int i; STATWORD ps; //kprintf("\nCalled XMUNMAP for <%d>",virtpage); /* sanity check ! */ if ( (virtpage < 4096) ){ kprintf("xmummap call error: virtpage (%d) invalid! \n", virtpage); return SYSERR; } disable(ps); write_back_data(currpid); for(i = 0; i < TOTAL_BS;i++) { if(bsm_tab[i].bs_status == BSM_UNMAPPED) continue; temp_bs = &bsm_tab[i]; while(temp_bs != NULL) { if(temp_bs->bs_vpno == virtpage) { /* Write the BS if mapped to the main memory */ if(prev_bs == NULL && temp_bs->next == NULL) { //write_back_data(currpid,i); /* This was the only mapping in the list and hence make the BSM available to use for other process */ //kprintf("\nOnly Mapping"); free_frm(i,temp_bs->bs_pid); free_bsm(i); //temp_bs->bs_status = BSM_UNMAPPED; } else { //write_back_data(currpid,i); //kprintf("\nRemoiving already mapped "); free_frm(i,temp_bs->bs_pid); temp_bs->bs_vpno = -1; //prev_bs->next = temp_bs->next; /* remove the node from the list as this is no more a valid mapping */ restore(ps); return OK; } } prev_bs = temp_bs; temp_bs = temp_bs->next; } } restore(ps); return SYSERR; }
/*------------------------------------------------------------------------- * kill_process - releases frames *------------------------------------------------------------------------- */ int kill_process(int pid) { int i; bs_map_t * bsmap; bs_map_t * prev; bs_map_t * curr; int pdbr,frame; STATWORD ps; disable(ps); for (i = 0; i < MAX_ID; i++) { bsmap = &bsm_tab[i]; if(bsmap->bs_status == BSM_UNMAPPED) continue; prev = bsmap; curr = bsmap->nextMap; while(curr != NULL) { if (curr->bs_pid == pid ) { xmunmap(curr->bs_vpno); } prev = curr; curr = curr->nextMap; } } pdbr = &proctab[pid].pdbr; frame = (pdbr/NBPG)-FRAME0; //release frame of page directory free_frm(frame); restore(ps); return OK; }
/******************************************************************************* * Name: remove_pgd * * Desc: Removes the pgd of a proc and frees the frame. * * Params: * pid - pid whose pgd has to be removed * * Returns: Nothing. ******************************************************************************/ void remove_pgd(int pid) { int pgd_fr_id = EMPTY; STATWORD ps; disable(ps); DTRACE_START; if (isbadpid(pid) || (PRFREE == P_GET_PSTATE(pid))) { DTRACE("DBG$ %d %s> bad pid %d or bad state %d\n", \ currpid, __func__, pid, P_GET_PSTATE(pid)); goto RESTORE_AND_RETURN; } /* Each process has a pdir whose base addr is stored in pgdir field of * the PCB. This is hosted on a frame and we need to free that frame as the * process is being killed. */ pgd_fr_id = FR_PA_TO_ID(P_GET_PDIR(pid)); free_frm(pgd_fr_id); RESTORE_AND_RETURN: DTRACE_END; restore(ps); return; }
/*------------------------------------------------------------------------- * get_frm - get a free frame according page replacement policy *------------------------------------------------------------------------- */ SYSCALL get_frm(int* avail) { //STATWORD ps; //disable(ps); int i = 0; int frame_number; // kprintf("get_frame called by pid %d and name %s\n", currpid, proctab[currpid].pname); for(i = 0; i < NFRAMES; i++) { // kprintf("Inside for loop in get frame\n"); if(frm_tab[i].fr_status == FRM_UNMAPPED) { *avail = i; // kprintf("Frame %d is found UNMAPPED and returned\n", i); return OK; } } { if(page_replace_policy == FIFO) { // kprintf("Frame to be removed\n"); frame_number = remove_frm_fifo(); if(frame_number == -1) return SYSERR; free_frm(frame_number); *avail = frame_number; // kprintf("Returned frame is %d\n", *avail); return OK; } else { frame_number = get_frm_LRU(); free_frm(frame_number); *avail = frame_number; return OK; } } //kprintf("To be implemented!\n"); //restore(ps); return OK; }
/*------------------------------------------------------------------------ * kill -- kill a process and remove it from the system *------------------------------------------------------------------------ */ SYSCALL kill(int pid) { STATWORD ps; struct pentry *pptr; /* points to proc. table for pid*/ int dev, pdbr; disable(ps); if (isbadpid(pid) || (pptr= &proctab[pid])->pstate==PRFREE) { restore(ps); return(SYSERR); } if (--numproc == 0) xdone(); dev = pptr->pdevs[0]; if (! isbaddev(dev) ) close(dev); dev = pptr->pdevs[1]; if (! isbaddev(dev) ) close(dev); dev = pptr->ppagedev; if (! isbaddev(dev) ) close(dev); send(pptr->pnxtkin, pid); proc_dies_clean_bs(pid); pdbr = proctab[pid].pdbr; //kprintf("\nFreeing frame in kill %d", (pdbr-FRAME0)); free_frm((pdbr-FRAME0)); freestk(pptr->pbase, pptr->pstklen); switch (pptr->pstate) { case PRCURR: pptr->pstate = PRFREE; /* suicide */ resched(); case PRWAIT: semaph[pptr->psem].semcnt++; case PRREADY: dequeue(pid); pptr->pstate = PRFREE; break; case PRSLEEP: case PRTRECV: unsleep(pid); /* fall through */ default: pptr->pstate = PRFREE; } restore(ps); return(OK); }
/*------------------------------------------------------------------------- * get_frm - get a free frame according page replacement policy *------------------------------------------------------------------------- */ SYSCALL get_frm(int* avail) { int i, j; STATWORD ps; disable(ps); for (i = 0; i < NFRAMES; i++) { if (frm_tab[i].fr_status == FRM_UNMAPPED) { init_frm(i); *avail = i; frm_tab[i].fr_status = FRM_MAPPED; //kprintf("get_frm returned %d\n",*avail); break; } } if (i == NFRAMES) { // kprintf("Ran out of free frames\n"); //indicates that we ran out of free frames. Implement page replacement policy and return a new frame as per the page replacement policy if (page_replace_policy == LRU) { *avail = next_frame(); //kprintf("get_frm returned %d\n",*avail); } else { *avail = getframe_fifoqueue(); } if (check_update_bs(*avail, frm_tab[*avail].fr_curr_bs, currpid) == OK) { frm_tab[*avail].fr_refcnt--; for (j = NPROC - 1; j > 0; j--) { if (frm_tab[*avail].fr_vpno[j] > 0 && frm_tab[*avail].fr_type == FR_PAGE) { //kprintf("fr_vpno[%d] = 0x%x\n",j,frm_tab[*avail].fr_vpno[j]); free_frm(*avail, j); } } //kprintf("ran out of free frames\n"); } frm_tab[*avail].fr_status = FRM_MAPPED; } //kprintf("get_frm returned %d\n",*avail); frm_tab[*avail].fr_pid = currpid; restore(ps); //kprintf("To be implemented!\n"); return OK; }
/*------------------------------------------------------------------------ * kill -- kill a process and remove it from the system *------------------------------------------------------------------------ */ SYSCALL kill(int pid) { STATWORD ps; struct pentry *pptr; /* points to proc. table for pid*/ int dev, i; disable(ps); if (isbadpid(pid) || (pptr= &proctab[pid])->pstate==PRFREE) { restore(ps); return(SYSERR); } if (--numproc == 0) xdone(); dev = pptr->pdevs[0]; if (! isbaddev(dev) ) close(dev); dev = pptr->pdevs[1]; if (! isbaddev(dev) ) close(dev); dev = pptr->ppagedev; if (! isbaddev(dev) ) close(dev); for(i = 0; i < NBS; i++) { bs_map_t *bs_ptr = &pptr->loc_bsm[i]; if(bs_ptr->bs_status == BSM_MAPPED){ bsm_unmap(pid,bs_ptr->bs_vpno, bs_ptr->bs_private); } free_bsm(i); } int source = pptr->pdbr/NBPG - FRAME0; free_frm(source); for(i = 0; i < NFRAMES; i++) { if(frm_tab[i].fr_pid == pid && frm_tab[i].fr_status == FRM_MAPPED){ //kprintf("freeing the frame %d for pid %d\n",i,pid); frm_tab[i].fr_status = FRM_UNMAPPED; frm_tab[i].fr_pid = UNDEFINED; frm_tab[i].fr_type = UNDEFINED; frm_tab[i].fr_refcnt = 0; frm_tab[i].fr_loadtime = UNDEFINED; frm_tab[i].fr_vpno = UNDEFINED; fifo_t *tmp = &fifo_head,*curr; while(tmp){ curr = tmp; tmp = tmp->fr_next; /*if(tmp && tmp->fr_id == -1) curr->fr_next = tmp->fr_next;*/ if(tmp && tmp->fr_id == i){ curr->fr_next = tmp->fr_next; //tmp->fr_next = NULL; break; } } } } fifo_t *tmp = &fifo_head,*curr; while(tmp){ curr = tmp; tmp = tmp->fr_next; /*if(tmp && tmp->fr_id == -1) curr->fr_next = tmp->fr_next;*/ if(tmp && (pid == frm_tab[tmp->fr_id].fr_pid)){ curr->fr_next = tmp->fr_next; //tmp->fr_next = NULL; } } send(pptr->pnxtkin, pid); freestk(pptr->pbase, pptr->pstklen); switch (pptr->pstate) { case PRCURR: pptr->pstate = PRFREE; /* suicide */ resched(); case PRWAIT: semaph[pptr->psem].semcnt++; case PRREADY: dequeue(pid); pptr->pstate = PRFREE; break; case PRSLEEP: case PRTRECV: unsleep(pid); /* fall through */ default: pptr->pstate = PRFREE; } restore(ps); return(OK); }