1 / 12

Kernel as a monitor

running. ready. CPU. Kernel as a monitor. signal (sem2). wait (sem2). sem2. wait (sem1). signal (sem1). sem1. suspend. resume. suspend. create. kill. pid qkey qnext qprev. 0. 1. 2 25 33 4. 3. 4 14 2 32.

marly
Download Presentation

Kernel as a monitor

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. running ready CPU Kernel as a monitor signal (sem2) wait (sem2) sem2 wait (sem1) signal (sem1) sem1 suspend resume suspend create kill SSST CS260

  2. pid qkey qnext qprev 0 1 2 25 33 4 3 4 14 2 32 5 NPROC - 1 NPROC Head at 32 MININT 4 ^ Tail at 33 MAXINT ^ 2 Queue as a linked list Head = 32 Tail = 33 4 2 ^ MININT 4 32 14 2 4 25 33 2 MAXINT ^ Kernel Queues /* q.h */ #define NQENT NPROC+NSEM+NSEM+4 struct qent { int qkey; int qnext; int qprev; } extern struct qent q[ ] ; extern int nextqueue; /* inline procedures*/ #define isempty(head) (q[(list)].qnext>=NPROC) #define nonempty(head) (q[(list)].qnext < NPROC) #define firstkey(head) (q[q[(head)].qnext].qkey) #define lastkey(tail) (q[q[(tail)].qprev].qkey)#define firstid(head) (q[(head)].qnext) #define EMPTY -1 q array of qent structures SSST CS260

  3. FIFO queue procedures /* dequeue – removes item from the list */ int dequeue (int item) { struct qent *mptr; mprt = &q[item]; q[mptr->qprev].qnext = mptr->qnext; /*1*/ q[mptr->qnext].qprev = mptr->qprev; /*2*/ return(item); } /* enqueue – insert item at the tail */ int enqueue (int item, int tail) { struct qent *tptr; struct qent *mptr; tptr = &q[tail]; mprt = &q[item]; mptr->qnext = tail; /* 1 */ mptr->qprev = tptr->qprev; /* 2 */ q[tptr->qprev].qnext = item; /* 3 */ tprt->qprev = item; /* 4 */ return(item); } prev item next 2 prev item tail 3 1 1 2 4 SSST CS260

  4. Priority queue procedures /* getfirst returns first process on the list */ int getfirst (int head) { int proc; if ( (proc = q[head].qnext) < NPROC) return(dequeue (proc) ); else return(EMPTY); } /* getlast returns last process from the list */ int getlast (int tail) { int proc; if ( (proc = q[tail].qprev) < NPROC) return(dequeue (proc) ); else return(EMPTY); } /* insert – insert item in priority order */ int insert (int proc, int head, int key) { int next; int prev; next = q[head].qnext; while (q[next].qkey < key) next = qnext[next].qnext; q[proc].qnext = next; /* 1 */ q[proc].qprev = prev = q[next].qprev; /*2*/ q[proc].qkey = key; /* 3 */ q[prev].qnext = proc; /* 4 */ q[next].qprev = proc; /* 5 */ return(OK); /* OK is 1 */ } SSST CS260

  5. Queue initialization /* newqueue intializes new linked list */ int newqueue ( ) { struct qent *hptr; struct qent *tptr; int hindex, tindex; hptr = &q[hindex = nextqueue++] ; /* nextqueue is global variable */ tptr = &q[tindex = nextqueue ++ ] ; hptr->qnext = tindex; hptr->qprev = EMPTY; hptr->qkey = MININT; tptr->qnext = EMPTY; tptr->qprev = hindex; tptr->qkey = MAXINT; return (hindex); } SSST CS260

  6. proc.h extern struct pentry proctab [ ] ; extern int numproc; /* no of currently active proc*/ extern int nextproc; /* next free slot */ extern int currpid; /* pid of running proc */ /* proc.h – isbadpid */ /* process state constants */ #define PRCURR ‘\01’ /* running */ #define PRFREE ‘\02’ /* process slot is free */ #define PRREADY ‘\03’ #define PRRECV ‘\04’ /* waiting for msg */ #define PRSLEEP ‘\05’ #define PRSUSP ‘\06’ /* suspended */ #define PRWAIT ‘\07’ /* waiting in sem que */ #define isbadpid(x) (x<=0 || x>=NPROC) struct pentry { char pstate; int pprio; int psem; /* sem where proc waits */ int pmsg; /* msg sent to this process */ char *pregs; /* saved regs (SP) */ char *pbase; /* base of the run-time stack */ word plen; /* stack length */ char pname[PNMLEN+1]; /* proc name */ int pargs; /* number of arguments */ int (*paddr) ( ); /* code address */ } SSST CS260

  7. resched.c #include <conf.h> #include <kernel.h> #include <proc.h> #include <q.h> int resched ( ) { register struct pentry *optr; register struct pentry *nptr; optr = &proctab[currpid]; if (optr->pstate == PRCURR) { if (lastkey(rdytail) < optr->pprio) return; /* no switch */ optr->pstate = PRREADY; insert(currpid, rdyhead, optr->pprio); } nptr = &proctab[ currpid = getlast(rdytail) ]; nptr->pstate = PRCURR; preempt = QUANTUM; /* no of ticks before preemption */ ctxsw ( &optr->pregs, &nptr->pregs ); /* the old process returns here when resumed */ return; } SSST CS260

  8. SP 100 rn 100 r1 flags bp bp ret addr SP optr 100 nptr 200 9 8 1 10 11 ctxsw.asm _ctxsw proc near • push bp • mov bp, sp • pushf ; push flags • cli ; clear interrupts • push r1 ; save regs on stack • . • push rn • mov bx, [bp + 4] • mov [bx], sp • mov bx, [bp + 6] • mov sp, [bx] • pop rn • . • pop r1 • popf • pop bp • ret SSST CS260

  9. ready – put a process in ready queue • #include <conf.h> • #include <kernel.h> • #include <proc.h> • #include <q.h> • int ready(int pid) { • register struct pentry *ppntr; • if (isbadpid(pid)) return(SYSERR); • ppntr = &proctab[pid]; • ppntr->pstate = PRREADY; • Insert (pid, rdyhead, ppntr->pprio); • return(OK); • } SSST CS260

  10. SYSCALL resume • #include <conf.h> • #include <kernel.h> • #include <proc.h> • SYSCALL resume(int pid) { • int ps; • struct pentry *ppntr; • int prio; • disable(ps); • if (isbadpid(pid) || (ppntr = &proctable[pid])->pstate != PRSUSP) { • restore(ps); • return(SYSERROR); • } • prio = ppntr->pprio; • ready(pid); • resched( ); • restore(ps); • return(prio); • } SSST CS260

  11. SYSCALL suspend • #include <conf.h> • #include <kernel.h> • #include <proc.h> • SYSCALL suspend(int pid) { • int ps; • struct pentry *ppntr; • int prio; • disable(ps); • if (isbadpid(pid) || pid == NULLPROC || ((ppntr = &proctable[pid])->pstate != PRREADY && ppntr->pstate != PRCURR ) { • restore(ps); • return(SYSERROR); • } • if (ppntr->pstate == PRREADY) { • dequeue(pid); • ppntr->pstate = PRSUSP; • } else { • ppntr->pstate = PRSUSP; • resched ( ) ; • } • prio = pptr->pprio; • restore(ps); • return(prio); • } SSST CS260

  12. SYSCALL kill • #include <conf.h> • #include <kernel.h> • #include <proc.h> • #include <mem.h> • #include <sem.h> • SYSCALL kill(int pid) { • int ps; • struct pentry *ppntr; • disable(ps); • if (isbadpid(pid) || (ppntr = • &proctable[pid])->pstate ==PRFREE) { • restore(ps); • return(SYSERROR); • } • if (--numproc == 0) xdone ( ); terminate Xinu • freestk (ppntr->pbase, ppntr->plen); switch (ppntr -> pstate) { case PRCURR: ppntr->pstate = PRFREE; resched ( ) ; case PRWAIT: semaph[pptr->psem].semcnt ++; case PRSLEEP: case PRREADY: dequeue(pid); default: ppntr->pstate = PRFREE; } restore(ps); return(OK); } SSST CS260

More Related