/*------------------------------------------------------------------------ * insertd - Insert a process in delta list using delay as the key *------------------------------------------------------------------------ */ status insertd( /* assumes interrupts disabled */ pid32 pid, /* ID of process to insert */ qid16 q, /* ID of queue to use */ int32 key /* delay from "now" (in ms.) */ ) { int next; /* runs through the delta list */ int prev; /* follows next through the list*/ if (isbadqid(q) || isbadpid(pid)) { return SYSERR; } prev = queuehead(q); next = queuetab[queuehead(q)].qnext; while ((next != queuetail(q)) && (queuetab[next].qkey <= key)) { key -= queuetab[next].qkey; prev = next; next = queuetab[next].qnext; } /* Insert new node between prev and next nodes */ queuetab[pid].qnext = next; queuetab[pid].qprev = prev; queuetab[pid].qkey = key; queuetab[prev].qnext = pid; queuetab[next].qprev = pid; if (next != queuetail(q)) { queuetab[next].qkey -= key; } return OK; }
/*------------------------------------------------------------------------ * copyqueue - Move the internal queue linked list of pids from one * queue to another by pointing the internal list at the other queue's * first and last id's. Any contents in the destination queue will be * dequeued first, and the source queue head and tail will be linked to * make the source queue empty. *------------------------------------------------------------------------ */ void copyqueue(qid16 srcq, qid16 destq) { while(!isempty(destq)) dequeue(destq); qid16 firstid = firstid(srcq); qid16 lastid = lastid(srcq); firstid(srcq) = queuetail(srcq); lastid(srcq) = queuehead(srcq); firstid(destq) = firstid; queuetab[firstid].qprev = queuehead(destq); lastid(destq) = lastid; queuetab[lastid].qnext = queuetail(destq); }
/*------------------------------------------------------------------------ * getlast - Remove a process from end of queue *------------------------------------------------------------------------ */ pid32 getlast( qid16 q /* ID of queue from which to */ ) /* remove a process (assumed */ /* valid with no check) */ { pid32 tail; if (isempty(q)) { return EMPTY; } tail = queuetail(q); return getitem(queuetab[tail].qprev); }
/*------------------------------------------------------------------------ * reward_ready_waiting - this method promotes all the processes on the readylist by giving them each an * increment of 6ms to their keys. We do this so that a process that has been waiting for a long time * would at least get a chance to execute if it had executed the cpu for a long time. * All processes in this ready list are processes that were not selected in this run of resched * as the next process to execute, despite being ready. Hence, this loss of opportunity is * defined as waiting in our context. * *------------------------------------------------------------------------ */ void reward_ready_waiting() { qid16 curr; /* Runs through items in a queue*/ qid16 prev; /* Holds previous node index */ struct procent * prptr; curr = firstid(readylist); while (curr != queuetail(readylist)) { prptr = &proctab[curr]; // don't promote prnull process if(curr!=0) queuetab[curr].qkey +=6; curr = queuetab[curr].qnext; } }
/** * Insert a process at the tail of a queue * @param pid process ID to enqueue * @param q queue to which the process should be added * @return process id of enqueued process */ short enqueue(short pid, queue q) { int tail; if (isbadqueue(q) || isbadpid(pid)) { return SYSERR; } tail = queuetail(q); queuetab[pid].next = tail; queuetab[pid].prev = queuetab[tail].prev; queuetab[queuetab[tail].prev].next = pid; queuetab[tail].prev = pid; return pid; }
/** * Reschedule processor to next ready process. * Upon entry, currpid gives current process id. Proctab[currpid].pstate * gives correct NEXT state for current process if other than PRREADY. * @return OK when the process is context switched back */ syscall resched(void) { irqmask im; pcb *oldproc; /* pointer to old process entry */ pcb *newproc; /* pointer to new process entry */ short head, tail; im = disable(); oldproc = &proctab[ currpid ]; /* Aging implemented */ if(AGING) { head = queuehead(readylist); head = queuetab[head].next; tail = queuetail(readylist); while(head != tail) { queuetab[head].key++; head = queuetab[head].next; } } /* place current process at end of ready queue */ if (PRCURR == oldproc->state) { oldproc->state = PRREADY; prioritize(currpid, readylist, oldproc->priority); } /* remove first process in ready queue */ currpid = dequeue(readylist); newproc = &proctab[ currpid ]; newproc->state = PRCURR; /* mark it currently running */ #if PREEMPT preempt = QUANTUM; /* reset preemption counter */ #endif ctxsw(&oldproc->stkptr, &newproc->stkptr); /* The OLD process returns here when resumed. */ restore(im); return OK; }
/*------------------------------------------------------------------------ * enqueue - Insert a process at the tail of a queue *------------------------------------------------------------------------ */ pid32 enqueue( pid32 pid, /* ID of process to insert */ qid16 q /* ID of queue to use */ ) { qid16 tail, prev; /* Tail & previous node indexes */ if (isbadqid(q) || isbadpid(pid)) { return SYSERR; } tail = queuetail(q); prev = queuetab[tail].qprev; queuetab[pid].qnext = tail; /* Insert just before tail node */ queuetab[pid].qprev = prev; queuetab[prev].qnext = pid; queuetab[tail].qprev = pid; return pid; }
pid32 enqueue(pid32 pid, qid16 qid) { if(isbadpid(pid) || isbadqid(qid)) { return SYSERR; } qid16 prev, tail; prev = lastid(qid); tail = queuetail(qid); queuetab[pid].qprev = prev; queuetab[pid].qnext = tail; queuetab[prev].qnext = pid; queuetab[tail].qprev = pid; return pid; }
qid16 newqueue(void) { static qid16 nextque = NPROC; qid16 qid, head, tail; qid = nextque; if(isbadqid(qid)) { return SYSERR; } nextque += 2; head = queuehead(qid); tail = queuetail(qid); queuetab[head].qnext = tail; queuetab[head].qprev = EMPTY; queuetab[head].qkey = MAXKEY; queuetab[tail].qnext = EMPTY; queuetab[tail].qprev = head; queuetab[tail].qkey = MINKEY; return qid; }