/*------------------------------------------------------------------------ * 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); }
/*------------------------------------------------------------------------ * getfirst - Remove a process from the front of a queue *------------------------------------------------------------------------ */ pid32 getfirst( qid16 q /* ID of queue from which to */ ) /* remove a process (assumed */ /* valid with no check) */ { pid32 head; if (isempty(q)) { return EMPTY; } head = queuehead(q); return getitem(queuetab[head].qnext); }
/** * Remove and return the first process on a list * @param q queue from which process should be removed * @return process id of removed process, or EMPTY */ short dequeue(queue q) { int head = queuehead(q); int pid; /* first process on the list */ if (isbadqueue(q)) { return SYSERR; } if ((pid = queuetab[head].next) < NPROC) { remove(pid); queuetab[pid].prev = pid; queuetab[pid].next = pid; return pid; } else { return EMPTY; } }
/** * 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; }
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; }