Removed unused code in proc.c. New message passing code with pointer pointers

is now in use. Rewrote ready() and unready() fuctions.
This commit is contained in:
Jorrit Herder 2005-06-20 11:26:48 +00:00
parent c9c6983cc1
commit 403580e95b
3 changed files with 36 additions and 147 deletions

View file

@ -14,21 +14,19 @@ g = $n/gen
CC = exec cc CC = exec cc
CPP = $l/cpp CPP = $l/cpp
LD = $(CC) -.o LD = $(CC) -.o
CFLAGS = -I$i CFLAGS = -I$i
LDFLAGS = -i LDFLAGS = -i
LIBS = -lsys -lutils -ltimers
HEAD = mpx.o HEAD = mpx.o
OBJS = start.o protect.o klibc.o klib.o table.o main.o proc.o \ OBJS = start.o protect.o klibc.o klib.o table.o main.o proc.o \
i8259.o exception.o system.o clock.o misc.o \ i8259.o exception.o system.o clock.o misc.o
SYS = system/system.a SYS = system/system.a
LIBS = -ltimers
# What to make. # What to make.
kernel build: $(HEAD) $(OBJS) $(SYS) kernel build: $(HEAD) $(OBJS) $(SYS)
$(LD) $(LDFLAGS) -o kernel $(HEAD) $(OBJS) $(SYS) $(CLOCK) $(LIBS) $(LD) $(CFLAGS) $(LDFLAGS) -o kernel $(HEAD) $(OBJS) $(SYS) $(LIBS)
install -S 0 kernel install -S 0 kernel
$(SYS): $(SYS):

View file

@ -39,15 +39,13 @@ FORWARD _PROTOTYPE( void shutdown, (timer_t *tp));
PUBLIC void main() PUBLIC void main()
{ {
/* Start the ball rolling. */ /* Start the ball rolling. */
register struct proc *rp; register struct proc *rp;
register int i; register int i;
int hdrindex; /* index to array of a.out headers */ int hdrindex; /* index to array of a.out headers */
phys_clicks text_base, bootdev_base; phys_clicks text_base;
vir_clicks text_clicks, bootdev_clicks; vir_clicks text_clicks;
vir_clicks data_clicks; vir_clicks data_clicks;
reg_t ktsb; /* kernel task stack base */ reg_t ktsb; /* kernel task stack base */
struct memory *memp;
struct system_image *ttp; struct system_image *ttp;
struct exec e_hdr; /* for a copy of an a.out header */ struct exec e_hdr; /* for a copy of an a.out header */

View file

@ -1,7 +1,3 @@
#define NEW_ELOCKED_CHECK 1
#define NEW_SCHED_Q 0
#define OLD_SEND 0
#define OLD_RECV 0
/* This file contains essentially all of the process and message handling. /* This file contains essentially all of the process and message handling.
* Together with "mpx.s" it forms the lowest layer of the MINIX kernel. * Together with "mpx.s" it forms the lowest layer of the MINIX kernel.
* There is one entry point from the outside: * There is one entry point from the outside:
@ -199,37 +195,16 @@ unsigned flags; /* system call flags */
* for this message, copy the message to it and unblock 'dst'. If 'dst' is * for this message, copy the message to it and unblock 'dst'. If 'dst' is
* not waiting at all, or is waiting for another source, queue 'caller_ptr'. * not waiting at all, or is waiting for another source, queue 'caller_ptr'.
*/ */
register struct proc *dst_ptr; register struct proc *dst_ptr = proc_addr(dst);
#if OLD_SEND
register struct proc *next_ptr;
register struct proc *xp;
#else
register struct proc **xpp; register struct proc **xpp;
register struct proc *xp; register struct proc *xp;
#endif
dst_ptr = proc_addr(dst); /* pointer to destination's proc entry */
/* Check for deadlock by 'caller_ptr' and 'dst' sending to each other. */ /* Check for deadlock by 'caller_ptr' and 'dst' sending to each other. */
#if NEW_ELOCKED_CHECK
xp = dst_ptr; xp = dst_ptr;
while (xp->p_flags & SENDING) { /* check while sending */ while (xp->p_flags & SENDING) { /* check while sending */
xp = proc_addr(xp->p_sendto); /* get xp's destination */ xp = proc_addr(xp->p_sendto); /* get xp's destination */
if (xp == caller_ptr) return(ELOCKED); /* deadlock if cyclic */ if (xp == caller_ptr) return(ELOCKED); /* deadlock if cyclic */
} }
#else
if (dst_ptr->p_flags & SENDING) {
next_ptr = proc_addr(dst_ptr->p_sendto);
while (TRUE) {
if (next_ptr == caller_ptr) return(ELOCKED);
if (next_ptr->p_flags & SENDING)
next_ptr = proc_addr(next_ptr->p_sendto);
else
break;
}
}
#endif
/* Check if 'dst' is blocked waiting for this message. The destination's /* Check if 'dst' is blocked waiting for this message. The destination's
* SENDING flag may be set when its SENDREC call blocked while sending. * SENDING flag may be set when its SENDREC call blocked while sending.
@ -248,19 +223,9 @@ unsigned flags; /* system call flags */
caller_ptr->p_sendto = dst; caller_ptr->p_sendto = dst;
/* Process is now blocked. Put in on the destination's queue. */ /* Process is now blocked. Put in on the destination's queue. */
#if OLD_SEND
if ( (next_ptr = dst_ptr->p_caller_q) == NIL_PROC)
dst_ptr->p_caller_q = caller_ptr;
else {
while (next_ptr->p_q_link != NIL_PROC)
next_ptr = next_ptr->p_q_link;
next_ptr->p_q_link = caller_ptr;
}
#else
xpp = &dst_ptr->p_caller_q; /* find end of list */ xpp = &dst_ptr->p_caller_q; /* find end of list */
while (*xpp != NIL_PROC) xpp = &(*xpp)->p_q_link; while (*xpp != NIL_PROC) xpp = &(*xpp)->p_q_link;
*xpp = caller_ptr; /* add caller to end */ *xpp = caller_ptr; /* add caller to end */
#endif
caller_ptr->p_q_link = NIL_PROC; /* mark new end of list */ caller_ptr->p_q_link = NIL_PROC; /* mark new end of list */
} else { } else {
return(ENOTREADY); return(ENOTREADY);
@ -281,12 +246,7 @@ unsigned flags; /* system call flags */
* acquire it and deblock the sender. If no message from the desired source * acquire it and deblock the sender. If no message from the desired source
* is available block the caller, unless the flags don't allow blocking. * is available block the caller, unless the flags don't allow blocking.
*/ */
#if OLD_RECV
register struct proc *sender_ptr;
register struct proc *previous_ptr;
#else
register struct proc **xpp; register struct proc **xpp;
#endif
register struct notification **ntf_q_pp; register struct notification **ntf_q_pp;
message m; message m;
int bit_nr; int bit_nr;
@ -298,23 +258,6 @@ unsigned flags; /* system call flags */
if (!(caller_ptr->p_flags & SENDING)) { if (!(caller_ptr->p_flags & SENDING)) {
/* Check caller queue. Use pointer pointers to keep code simple. */ /* Check caller queue. Use pointer pointers to keep code simple. */
#if OLD_RECV /* to hairy, unreadable */
for (sender_ptr = caller_ptr->p_caller_q; sender_ptr != NIL_PROC;
previous_ptr = sender_ptr, sender_ptr = sender_ptr->p_q_link) {
if (src == ANY || src == proc_nr(sender_ptr)) {
/* An acceptable message has been found. */
CopyMess(sender_ptr->p_nr, sender_ptr,
sender_ptr->p_messbuf, caller_ptr, m_ptr);
if (sender_ptr == caller_ptr->p_caller_q)
caller_ptr->p_caller_q = sender_ptr->p_q_link;
else
previous_ptr->p_q_link = sender_ptr->p_q_link;
if ((sender_ptr->p_flags &= ~SENDING) == 0)
ready(sender_ptr); /* deblock sender */
return(OK);
}
}
#else
xpp = &caller_ptr->p_caller_q; xpp = &caller_ptr->p_caller_q;
while (*xpp != NIL_PROC) { while (*xpp != NIL_PROC) {
if (src == ANY || src == proc_nr(*xpp)) { if (src == ANY || src == proc_nr(*xpp)) {
@ -326,7 +269,6 @@ unsigned flags; /* system call flags */
} }
xpp = &(*xpp)->p_q_link; /* proceed to next */ xpp = &(*xpp)->p_q_link; /* proceed to next */
} }
#endif
/* Check if there are pending notifications, except for SENDREC. */ /* Check if there are pending notifications, except for SENDREC. */
if (! (flags & FRESH_ANSWER)) { if (! (flags & FRESH_ANSWER)) {
@ -507,33 +449,19 @@ register struct proc *rp; /* this process is now runnable */
* user processes are added in front of the queue, because this is a bit * user processes are added in front of the queue, because this is a bit
* fairer to I/O bound processes. * fairer to I/O bound processes.
*/ */
#if NEW_SCHED_Q if (rdy_head[q] == NIL_PROC) { /* add to empty queue */
if (isuserp(rp)) { /* add to front of queue */ rdy_head[q] = rdy_tail[q] = rp; /* create a new queue */
rp->p_nextready = rdy_head[q]; /* chain current front */ rp->p_nextready = NIL_PROC; /* mark new end */
rdy_head[q] = rp; /* rp becomes new front */
}
else { /* add to end of queue */
xpp = &rdy_head[q]; /* find pointer to end */
while (*xpp != NIL_PROC) xpp = &(*xpp)->p_nextready;
*xpp = rp; /* replace end with rp */
rp->p_nextready = NIL_PROC; /* mark end of queue */
}
#else
if (isuserp(rp)) { /* add to front of queue */
if (rdy_head[q] == NIL_PROC)
rdy_tail[q] = rp;
rp->p_nextready = rdy_head[q]; /* add to front of queue */
rdy_head[q] = rp;
} }
else { else if (isuserp(rp)) { /* add to head of queue */
if (rdy_head[q] != NIL_PROC) rp->p_nextready = rdy_head[q]; /* chain head of queue */
rdy_tail[q]->p_nextready = rp; /* add to end of queue */ rdy_head[q] = rp; /* set new queue head */
else }
rdy_head[q] = rp; /* add to empty queue */ else { /* add to tail of queue */
rdy_tail[q] = rp; rdy_tail[q]->p_nextready = rp; /* chain tail of queue */
rp->p_nextready = NIL_PROC; rdy_tail[q] = rp; /* set new queue tail */
rp->p_nextready = NIL_PROC; /* mark new end */
} }
#endif
/* Run 'rp' next if it has a higher priority than 'proc_ptr' or 'next_ptr'. /* Run 'rp' next if it has a higher priority than 'proc_ptr' or 'next_ptr'.
* This actually should be done via pick_proc(), but the message passing * This actually should be done via pick_proc(), but the message passing
@ -552,12 +480,8 @@ register struct proc *rp; /* this process is no longer runnable */
/* A process has blocked. See ready for a description of the queues. */ /* A process has blocked. See ready for a description of the queues. */
register int q = rp->p_priority; /* queue to use */ register int q = rp->p_priority; /* queue to use */
#if NEW_SCHED_Q
register struct proc **xpp; /* iterate over queue */ register struct proc **xpp; /* iterate over queue */
#else register struct proc *prev_xp;
register struct proc **qtail; /* queue's rdy_tail */
register struct proc *xp;
#endif
#if ENABLE_K_DEBUGGING #if ENABLE_K_DEBUGGING
if(!rp->p_ready) { if(!rp->p_ready) {
@ -576,71 +500,40 @@ register struct proc *rp; /* this process is no longer runnable */
* process if it is found. A process can be made unready even if it is not * process if it is found. A process can be made unready even if it is not
* running by being sent a signal that kills it. * running by being sent a signal that kills it.
*/ */
#if NEW_SCHED_Q prev_xp = NIL_PROC;
xpp = &rdy_head[q]; for (xpp = &rdy_head[q]; *xpp != NIL_PROC; xpp = &(*xpp)->p_nextready) {
while (*xpp != NIL_PROC) { /* check entire queue */
if (*xpp == rp) { /* lookup unready process */ if (*xpp == rp) { /* found process to remove */
*xpp = (*xpp)->p_nextready; /* replace it with next */ *xpp = (*xpp)->p_nextready; /* replace with next chain */
if (rp == proc_ptr || rp == next_ptr) /* current process removed */ if (rp == rdy_tail[q]) /* queue tail removed */
rdy_tail[q] = prev_xp; /* set new tail */
if (rp == proc_ptr || rp == next_ptr) /* active process removed */
pick_proc(); /* pick new process to run */ pick_proc(); /* pick new process to run */
break; break;
} }
xpp = &(*xpp)->p_nextready; /* proceed to next */ prev_xp = *xpp; /* save previous in chain */
} }
#else
if ( (xp = rdy_head[q]) != NIL_PROC) { /* ready queue is empty */
if (xp == rp) { /* check head of queue */
rdy_head[q] = xp->p_nextready; /* new head of queue */
if (rp == proc_ptr || rp == next_ptr) /* current process removed */
pick_proc(); /* pick new process to run */
if(rp == rdy_tail[q])
rdy_tail[q] = NIL_PROC;
}
else { /* check body of queue */
while (xp->p_nextready != rp) /* stop if process is next */
if ( (xp = xp->p_nextready) == NIL_PROC)
return;
xp->p_nextready = xp->p_nextready->p_nextready;
if (rdy_tail[q] == rp) /* possibly update tail */
rdy_tail[q] = xp;
}
}
#endif
} }
/*===========================================================================* /*===========================================================================*
* sched * * sched *
*===========================================================================*/ *===========================================================================*/
PRIVATE void sched(queue) PRIVATE void sched(q)
int queue; int q; /* scheduling queue to use */
{ {
/* The current process has run too long. If another low priority (user) /* The current process has run too long. If another low priority (user)
* process is runnable, put the current process on the end of the user queue, * process is runnable, put the current process on the end of the user queue,
* possibly promoting another user to head of the queue. * possibly promoting another user to head of the queue.
*/ */
register struct proc **xpp; if (rdy_head[q] == NIL_PROC) return; /* return for empty queue */
register struct proc *xp;
if (rdy_head[queue] == NIL_PROC) return;
/* One or more user processes queued. */ /* One or more user processes queued. */
#if NEW_SCHED_Q rdy_tail[q]->p_nextready = rdy_head[q]; /* add expired to end */
rdy_tail[q] = rdy_head[q]; /* set new queue tail */
rdy_head[q] = rdy_head[q]->p_nextready; /* set new queue head */
rdy_tail[q]->p_nextready = NIL_PROC; /* mark new queue end */
xp = rdy_head[queue]; /* save expired process */ pick_proc(); /* select next to run */
rdy_head[queue] = xp->p_nextready; /* advance to next process */
xpp = &rdy_head[queue]; /* find end of queue */
while (*xpp != NIL_PROC) xpp = &(*xpp)->p_nextready;
*xpp = xp; /* add expired to end */
xp->p_nextready = NIL_PROC; /* mark new end of queue */
#else
rdy_tail[queue]->p_nextready = rdy_head[queue]; /* add expired to end */
rdy_tail[queue] = rdy_head[queue]; /* set new tail */
rdy_head[queue] = rdy_head[queue]->p_nextready; /* set new head */
rdy_tail[queue]->p_nextready = NIL_PROC; /* mark new end */
#endif
pick_proc();
} }