From: Jorrit Herder Date: Thu, 26 May 2005 13:17:57 +0000 (+0000) Subject: Optimized scheduling code. Old code is still available withing DEAD_CODE X-Git-Tag: v3.1.0~812 X-Git-Url: http://zhaoyanbai.com/repos/%22/xml/v3/status/static/gitweb.js?a=commitdiff_plain;h=77c3213948eb2b1a42689ce4dbc050983bc51c21;p=minix.git Optimized scheduling code. Old code is still available withing DEAD_CODE and NEW_SCHED_Q definitions. Some minor problems are being traced at the moment. This commit is meant to backup my files. --- Jorrit --- diff --git a/drivers/tty/console.c b/drivers/tty/console.c index adcd2c87c..0f98a1416 100644 --- a/drivers/tty/console.c +++ b/drivers/tty/console.c @@ -869,11 +869,17 @@ message *m; int r; /* Try to get a fresh copy of the buffer with kernel messages. */ - r=0; +#if DEAD_CODE + /* During shutdown, the reply is garbled because new notifications arrive + * while the system task makes a copy of the kernel messages buffer. + * Hence, don't check the return value. + */ if ((r=sys_getkmessages(&kmess)) != OK) { printf("TTY: couldn't get copy of kmessages: %d, 0x%x\n", r,r); return; } +#endif + sys_getkmessages(&kmess); /* Print only the new part. Determine how many new bytes there are with * help of the current and previous 'next' index. Note that the kernel diff --git a/drivers/tty/keyboard.c b/drivers/tty/keyboard.c index 5aaacced7..62c1c34ed 100644 --- a/drivers/tty/keyboard.c +++ b/drivers/tty/keyboard.c @@ -526,13 +526,23 @@ int scode; /* scan code for a function key */ /* See if an observer is registered and send it a message. */ if (observers[index] != NONE) { +#if DEAD_CODE m.m_type = FKEY_PRESSED; m.FKEY_NUM = index+1; m.FKEY_CODE = fkey; if (OK != (s=nb_send(observers[index], &m))) { - printf("WARNING: F%d key notification to process %d failed: %d.\n", + printf("WARNING: F%d key nb_send to process %d failed: %d.\n", index+1, observers[index], s); } +#else + m.NOTIFY_TYPE = FKEY_PRESSED; + m.NOTIFY_ARG = fkey; + m.NOTIFY_FLAGS = index+1; + if (OK != (s=notify(observers[index], &m))) { + printf("WARNING: F%d key notify to process %d failed: %d.\n", + index+1, observers[index], s); + } +#endif } return(TRUE); } diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index 03b527077..e3d7d035e 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -145,6 +145,7 @@ PUBLIC timer_t *tty_timers; /* queue of TTY timers */ PUBLIC clock_t tty_next_timeout; /* time that the next alarm is due */ PUBLIC struct machine machine; /* kernel environment variables */ + static int debug = 0; /*===========================================================================* * tty_task * @@ -192,6 +193,11 @@ PUBLIC void main(void) * request and should be handled separately. These extra functions * do not operate on a device, in constrast to the driver requests. */ + if (debug) { + printf("TTY got request from %d, type %d\n", + tty_mess.m_source, tty_mess.m_type); + printf("???\n"); + } switch (tty_mess.m_type) { case SYN_ALARM: /* fall through */ case HARD_INT: /* hardware interrupt notification */ @@ -204,8 +210,12 @@ PUBLIC void main(void) case HARD_STOP: { /* MINIX is going down */ static int stop = 0; /* expect two HARD_STOP messages */ if (! stop++) { + printf("TTY got first HARD_STOP message\n"); + debug = 1; cons_stop(); /* first switch to primary console */ + printf("TTY returned from cons_stop()\n"); } else { + printf("TTY got second HARD_STOP message\n"); if(irq_hook_id != -1) { int r; r = sys_irqdisable(&irq_hook_id); @@ -222,7 +232,9 @@ PUBLIC void main(void) do_panic_dumps(&tty_mess); continue; case DIAGNOSTICS: /* a server wants to print some */ + if (debug) printf("TTY get DIAG\n"); do_diagnostics(&tty_mess); + if (debug) printf("TTY finished DIAG\n"); continue; case FKEY_CONTROL: /* (un)register a fkey observer */ do_fkey_ctl(&tty_mess); @@ -1302,8 +1314,12 @@ int status; /* reply code */ tty_mess.m_type = code; tty_mess.REP_PROC_NR = proc_nr; tty_mess.REP_STATUS = status; - if ((status = send(replyee, &tty_mess)) != OK) + if (debug) + printf("TTY wanted to send to %d, type %d, status %d\n", + proc_nr, code, status); + if ((status = send(replyee, &tty_mess)) != OK) { server_panic("TTY","tty_reply failed, status\n", status); + } } diff --git a/kernel/clock.c b/kernel/clock.c index a51ea654c..a35090bd2 100755 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -118,7 +118,7 @@ PUBLIC void clock_task() result = do_clocktick(&m); /* handle clock tick */ break; default: /* illegal message type */ - kprintf("CLOCK got illegal request from %d.\n", m.m_source); + kprintf("Warning, illegal CLOCK request from %d.\n", m.m_source); result = EBADREQUEST; } @@ -128,7 +128,8 @@ PUBLIC void clock_task() */ if (result != EDONTREPLY) { m.m_type = result; - lock_send(m.m_source, &m); + if (OK != lock_send(m.m_source, &m)) + kprintf("Warning, CLOCK couldn't reply to %d.\n", m.m_source); } } } @@ -155,9 +156,10 @@ message *m_ptr; /* pointer to request message */ TMR_NEVER : clock_timers->tmr_exp_time; } - /* If a user process has been running too long, pick another one. */ - if (--sched_ticks == 0) { - if (bill_ptr == prev_ptr) lock_sched(); /* process has run too long */ + /* If a process has been running too long, pick another one. */ + if (--sched_ticks <= 0) { + if (bill_ptr == prev_ptr) + lock_sched(PPRI_USER); /* process has run too long */ sched_ticks = SCHED_RATE; /* reset quantum */ prev_ptr = bill_ptr; /* new previous process */ } @@ -249,7 +251,7 @@ irq_hook_t *hook; m.NOTIFY_TYPE = HARD_INT; lock_notify(CLOCK, &m); } - else if (--sched_ticks == 0) { + else if (--sched_ticks <= 0) { sched_ticks = SCHED_RATE; /* reset the quantum */ prev_ptr = bill_ptr; /* new previous process */ } diff --git a/kernel/exception.c b/kernel/exception.c index c96682352..6f97dca54 100755 --- a/kernel/exception.c +++ b/kernel/exception.c @@ -57,7 +57,7 @@ unsigned vec_nr; if (k_reenter == 0 && ! istaskp(saved_proc)) { unlock(); /* this is protected like sys_call() */ - cause_sig(proc_number(saved_proc), ep->signum); + cause_sig(proc_nr(saved_proc), ep->signum); return; } @@ -66,7 +66,7 @@ unsigned vec_nr; kprintf("\nIntel-reserved exception %d\n", vec_nr); else kprintf("\n%s\n", karg(ep->msg)); - kprintf("process number %d, ", proc_number(saved_proc)); + kprintf("process number %d, ", proc_nr(saved_proc)); kprintf("pc = %d:", (unsigned) saved_proc->p_reg.cs); kprintf("0x%x\n", (unsigned) saved_proc->p_reg.pc); diff --git a/kernel/main.c b/kernel/main.c index 905ee8929..c324d9a73 100755 --- a/kernel/main.c +++ b/kernel/main.c @@ -55,7 +55,7 @@ PUBLIC void main() intr_init(1); /* Clear the process table. Anounce each slot as empty and - * set up mappings for proc_addr() and proc_number() macros. + * set up mappings for proc_addr() and proc_nr() macros. */ for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) { rp->p_type = P_NONE; /* isemptyp() tests on this */ @@ -146,7 +146,6 @@ PUBLIC void main() #if ENABLE_K_DEBUGGING rp->p_ready = 0; #endif - if (rp->p_nr != HARDWARE) lock_ready(rp); rp->p_flags = 0; @@ -271,7 +270,6 @@ timer_t *tp; */ static int level = P_SERVER; /* start at the highest level */ static struct proc *p = NIL_PROC; /* next process to stop */ - static char *types[] = {"task","system","driver","server","user"}; static message m; /* See if the last process' shutdown was successful. Else, force exit. */ @@ -291,13 +289,11 @@ timer_t *tp; if (p == NIL_PROC) p = BEG_PROC_ADDR; while (TRUE) { if (isalivep(p) && p->p_type == level) { /* found a process */ - int w; - kprintf("- Stopping %s ", karg(p->p_name)); - kprintf("%s ... ", karg(types[p->p_type])); + kprintf("- Stopping %s ... ", karg(p->p_name)); shutdown_process = p; /* directly continue if exited */ m.NOTIFY_TYPE = HARD_STOP; m.NOTIFY_ARG = tmr_arg(tp)->ta_int; /* how */ - lock_notify(proc_number(p), &m); + lock_notify(proc_nr(p), &m); set_timer(tp, get_uptime()+STOP_TICKS, stop_sequence); return; /* allow the process to shut down */ } diff --git a/kernel/misc.c b/kernel/misc.c index e4acc8078..37da8b924 100755 --- a/kernel/misc.c +++ b/kernel/misc.c @@ -104,7 +104,6 @@ bit_t nr_bits; return(bit_nr); } - kprintf("Warning, all %d bits in map busy\n", nr_bits); return(-1); } diff --git a/kernel/proc.c b/kernel/proc.c index c0a6f8124..4391b9d2b 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -1,3 +1,4 @@ +#define NEW_SCHED_Q 1 /* This file contains essentially all of the process and message handling. * It has one main entry point from the outside: * @@ -13,6 +14,7 @@ * lock_pick_proc: pick a process to run (used by system initialization) * * Changes: + * May 26, 2005 optimized message passing functions (Jorrit N. Herder) * May 24, 2005 new, queued NOTIFY system call (Jorrit N. Herder) * Oct 28, 2004 non-blocking SEND and RECEIVE (Jorrit N. Herder) * Oct 28, 2004 rewrite of sys_call() (Jorrit N. Herder) @@ -33,21 +35,22 @@ * interrupts to prevent race conditions. */ FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst, - message *m_ptr, int may_block) ); + message *m_ptr, int flags) ); FORWARD _PROTOTYPE( int mini_rec, (struct proc *caller_ptr, int src, - message *m_ptr, int may_block) ); + message *m_ptr, int flags) ); FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dst, message *m_ptr ) ); FORWARD _PROTOTYPE( void ready, (struct proc *rp) ); -FORWARD _PROTOTYPE( void sched, (void) ); +FORWARD _PROTOTYPE( void sched, (int queue) ); FORWARD _PROTOTYPE( void unready, (struct proc *rp) ); FORWARD _PROTOTYPE( void pick_proc, (void) ); -#if (CHIP == M68000) -FORWARD _PROTOTYPE( void cp_mess, (int src, struct proc *src_p, message *src_m, - struct proc *dst_p, message *dst_m) ); -#endif +#define BuildMess(m,n) \ + (m).NOTIFY_SOURCE = (n)->n_source, \ + (m).NOTIFY_TYPE = (n)->n_type, \ + (m).NOTIFY_FLAGS = (n)->n_flags, \ + (m).NOTIFY_ARG = (n)->n_arg; #if (CHIP == INTEL) #define CopyMess(s,sp,sm,dp,dm) \ @@ -80,61 +83,77 @@ message *m_ptr; /* pointer to message in the caller's space */ */ register struct proc *caller_ptr = proc_ptr; /* get pointer to caller */ int function = call_nr & SYSCALL_FUNC; /* get system call function */ - int may_block = ! (call_nr & NON_BLOCKING); /* (dis)allow blocking? */ + int flags = call_nr & SYSCALL_FLAGS; /* get flags */ int mask_entry; /* bit to check in send mask */ int result; /* the system call's result */ + vir_bytes vb; /* message buffer pointer as vir_bytes */ + vir_clicks vlo, vhi; /* virtual clicks containing message to send */ /* Calls directed to the kernel may only be sendrec(), because tasks always * reply and may not block if the caller doesn't do receive(). Users also * may only use sendrec() to protect the process manager and file system. */ -#if DEAD_CODE - if ((iskernel(src_dst) || isuserp(caller_ptr)) && function != BOTH) { -#else - if (iskernel(src_dst) && function != BOTH) { -#endif - result = ECALLDENIED; /* BOTH was required */ - } + if (iskernel(src_dst) && function != BOTH) + return(ECALLDENIED); /* BOTH was required */ /* Verify that requested source and/ or destination is a valid process. */ - else if (! isoksrc_dst(src_dst)) { - result = EBADSRCDST; /* invalid process number */ - } + if (! isoksrc_dst(src_dst)) + return(EBADSRCDST); + + /* Check validity of message pointer. */ + vb = (vir_bytes) m_ptr; + vlo = vb >> CLICK_SHIFT; /* vir click for bottom of message */ + vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* vir click for top of msg */ +#if ALLOW_GAP_MESSAGES + /* This check allows a message to be anywhere in data or stack or gap. + * It will have to be made more elaborate later for machines which + * don't have the gap mapped. + */ + if (vlo < caller_ptr->p_memmap[D].mem_vir || vlo > vhi || + vhi >= caller_ptr->p_memmap[S].mem_vir + caller_ptr->p_memmap[S].mem_len) + return(EFAULT); +#else + /* Check for messages wrapping around top of memory or outside data seg. */ + if (vhi < vlo || + vhi - caller_ptr->p_memmap[D].mem_vir >= caller_ptr->p_memmap[D].mem_len) + return(EFAULT); +#endif /* Now check if the call is known and try to perform the request. The only * system calls that exist in MINIX are sending and receiving messages. * Receiving is straightforward. Sending requires to check caller's send * mask and whether the destination is alive. */ - else { - switch(function) { - case SEND: - /* fall through, SEND is done in BOTH */ - case BOTH: - if (! isalive(src_dst)) { - result = EDEADDST; /* cannot send to the dead */ - break; - } - mask_entry = isuser(src_dst) ? USER_PROC_NR : src_dst; - if (! isallowed(caller_ptr->p_sendmask, mask_entry)) { - kprintf("WARNING: sys_call denied %d ", caller_ptr->p_nr); - kprintf("sending to %d\n", proc_addr(src_dst)->p_nr); - result = ECALLDENIED; /* call denied by send mask */ - break; - } - result = mini_send(caller_ptr, src_dst, m_ptr, may_block); - if (function == SEND || result != OK) { - break; /* done, or SEND failed */ - } /* fall through for BOTH */ - case RECEIVE: - result = mini_rec(caller_ptr, src_dst, m_ptr, may_block); + switch(function) { + case SEND: + /* fall through, SEND is done in BOTH */ + case BOTH: + if (! isalive(src_dst)) { + result = EDEADDST; /* cannot send to the dead */ break; - case NOTIFY: - result = mini_notify(caller_ptr, src_dst, m_ptr); - break; - default: - result = EBADCALL; /* illegal system call */ } + mask_entry = isuser(src_dst) ? USER_PROC_NR : src_dst; + if (! isallowed(caller_ptr->p_sendmask, mask_entry)) { + kprintf("WARNING: sys_call denied %d ", caller_ptr->p_nr); + kprintf("sending to %d\n", proc_addr(src_dst)->p_nr); + result = ECALLDENIED; /* call denied by send mask */ + break; + } + + result = mini_send(caller_ptr, src_dst, m_ptr, + ! (flags & NON_BLOCKING) ); + if (function == SEND || result != OK) { + break; /* done, or SEND failed */ + } /* fall through for BOTH */ + case RECEIVE: + result = mini_rec(caller_ptr, src_dst, m_ptr, + ! (flags & NON_BLOCKING) ); + break; + case NOTIFY: + result = mini_notify(caller_ptr, src_dst, m_ptr); + break; + default: + result = EBADCALL; /* illegal system call */ } /* Now, return the result of the system call to the caller. */ @@ -145,44 +164,28 @@ message *m_ptr; /* pointer to message in the caller's space */ /*===========================================================================* * mini_send * *===========================================================================*/ -PRIVATE int mini_send(caller_ptr, dst, m_ptr, may_block) +PRIVATE int mini_send(caller_ptr, dst, m_ptr, flags) register struct proc *caller_ptr; /* who is trying to send a message? */ int dst; /* to whom is message being sent? */ message *m_ptr; /* pointer to message buffer */ -int may_block; /* (dis)allow blocking */ +int flags; /* system call flags */ { /* Send a message from 'caller_ptr' to 'dst'. If 'dst' is blocked waiting * 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'. */ - register struct proc *dst_ptr, *next_ptr; - vir_bytes vb; /* message buffer pointer as vir_bytes */ - vir_clicks vlo, vhi; /* virtual clicks containing message to send */ + register struct proc *dst_ptr; +#if DEAD_CODE + register struct proc *next_ptr; +#endif + register struct proc *xp; + register struct proc **xpp; dst_ptr = proc_addr(dst); /* pointer to destination's proc entry */ -#if ALLOW_GAP_MESSAGES - /* This check allows a message to be anywhere in data or stack or gap. - * It will have to be made more elaborate later for machines which - * don't have the gap mapped. + /* Check for deadlock by 'caller_ptr' and 'dst' sending to each other. + * This check is rare, so overhead is acceptable. */ - vb = (vir_bytes) m_ptr; - vlo = vb >> CLICK_SHIFT; /* vir click for bottom of message */ - vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* vir click for top of msg */ - if (vlo < caller_ptr->p_memmap[D].mem_vir || vlo > vhi || - vhi >= caller_ptr->p_memmap[S].mem_vir + caller_ptr->p_memmap[S].mem_len) - return(EFAULT); -#else - /* Check for messages wrapping around top of memory or outside data seg. */ - vb = (vir_bytes) m_ptr; - vlo = vb >> CLICK_SHIFT; /* vir click for bottom of message */ - vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* vir click for top of msg */ - if (vhi < vlo || - vhi - caller_ptr->p_memmap[D].mem_vir >= caller_ptr->p_memmap[D].mem_len) - return(EFAULT); -#endif - - /* Check for deadlock by 'caller_ptr' and 'dst' sending to each other. */ if (dst_ptr->p_flags & SENDING) { next_ptr = proc_addr(dst_ptr->p_sendto); while (TRUE) { @@ -194,16 +197,17 @@ int may_block; /* (dis)allow blocking */ } } - /* Check to see if 'dst' is blocked waiting for this message. */ + /* Check if 'dst' is blocked waiting for this message. The destination's + * SENDING flag may be set when BOTH couldn't send. Await a pure RECEIVE. + */ if ( (dst_ptr->p_flags & (RECEIVING | SENDING)) == RECEIVING && - (dst_ptr->p_getfrom == ANY || - dst_ptr->p_getfrom == proc_number(caller_ptr))) { + (dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) { /* Destination is indeed waiting for this message. */ - CopyMess(proc_number(caller_ptr), caller_ptr, m_ptr, dst_ptr, + CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, dst_ptr, dst_ptr->p_messbuf); dst_ptr->p_flags &= ~RECEIVING; /* deblock destination */ if (dst_ptr->p_flags == 0) ready(dst_ptr); - } else if (may_block) { + } else if (flags) { /* Destination is not waiting. Block and queue caller. */ caller_ptr->p_messbuf = m_ptr; if (caller_ptr->p_flags == 0) unready(caller_ptr); @@ -211,14 +215,20 @@ int may_block; /* (dis)allow blocking */ caller_ptr->p_sendto = dst; /* Process is now blocked. Put in on the destination's queue. */ +#if DEAD_CODE if ( (next_ptr = dst_ptr->p_caller_q) == NIL_PROC) dst_ptr->p_caller_q = caller_ptr; else { - while (next_ptr->p_sendlink != NIL_PROC) - next_ptr = next_ptr->p_sendlink; - next_ptr->p_sendlink = caller_ptr; + while (next_ptr->p_q_link != NIL_PROC) + next_ptr = next_ptr->p_q_link; + next_ptr->p_q_link = caller_ptr; } - caller_ptr->p_sendlink = NIL_PROC; +#else + xpp = &dst_ptr->p_caller_q; + while (*xpp != NIL_PROC) xpp = &(*xpp)->p_q_link; + *xpp = caller_ptr; +#endif + caller_ptr->p_q_link = NIL_PROC; } else { return(ENOTREADY); } @@ -228,69 +238,89 @@ int may_block; /* (dis)allow blocking */ /*===========================================================================* * mini_rec * *===========================================================================*/ -PRIVATE int mini_rec(caller_ptr, src, m_ptr, may_block) +PRIVATE int mini_rec(caller_ptr, src, m_ptr, flags) register struct proc *caller_ptr; /* process trying to get message */ int src; /* which message source is wanted */ message *m_ptr; /* pointer to message buffer */ -int may_block; /* (dis)allow blocking */ +int flags; /* system call flags */ { /* A process or task wants to get a message. If one is already queued, * acquire it and deblock the sender. If no message from the desired source * is available, block the caller. */ +#if DEAD_CODE register struct proc *sender_ptr; register struct proc *previous_ptr; +#endif + register struct proc **xpp; register struct notification **ntf_q_pp; message m; - int bit_nr, i; + int bit_nr; - /* Check to see if a message from desired source is already available. */ + /* Check to see if a message from desired source is already available. + * The caller's SENDING flag may be set if BOTH couldn't send. If it is + * set, the process should be blocked. + */ if (!(caller_ptr->p_flags & SENDING)) { - /* Check caller queue. */ + /* Check caller queue. Use pointer pointers to keep code simple. */ +#if DEAD_CODE /* to hairy, unreadable */ for (sender_ptr = caller_ptr->p_caller_q; sender_ptr != NIL_PROC; - previous_ptr = sender_ptr, sender_ptr = sender_ptr->p_sendlink) { - if (src == ANY || src == proc_number(sender_ptr)) { + 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(proc_number(sender_ptr), sender_ptr, + 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_sendlink; + caller_ptr->p_caller_q = sender_ptr->p_q_link; else - previous_ptr->p_sendlink = sender_ptr->p_sendlink; + 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; + while (*xpp != NIL_PROC) { + if (src == ANY || src == proc_nr(*xpp)) { + /* An acceptable source has been found. Copy the message to the + * caller, update the sender's status, and remove the sender from + * the caller's queue. + */ + CopyMess((*xpp)->p_nr, *xpp, (*xpp)->p_messbuf, caller_ptr, m_ptr); + if (((*xpp)->p_flags &= ~SENDING) == 0) ready(*xpp); + *xpp = (*xpp)->p_q_link; /* remove from queue */ + return(OK); + } + xpp = &(*xpp)->p_q_link; /* proceed to next */ + } +#endif + /* Check if there are pending notifications. */ ntf_q_pp = &caller_ptr->p_ntf_q; /* get pointer pointer */ - while (*ntf_q_pp) { + while (*ntf_q_pp != NULL) { if (src == ANY || src == (*ntf_q_pp)->n_source) { /* Found notification. Assemble and copy message. */ - m.NOTIFY_SOURCE = (*ntf_q_pp)->n_source; - m.NOTIFY_TYPE = (*ntf_q_pp)->n_type; - m.NOTIFY_FLAGS = (*ntf_q_pp)->n_flags; - m.NOTIFY_ARG = (*ntf_q_pp)->n_arg; + BuildMess(m, *ntf_q_pp); CopyMess((*ntf_q_pp)->n_source, proc_addr(HARDWARE), &m, caller_ptr, m_ptr); - /* Remove notification from queue and return. */ + /* Remove notification from queue and bit map. */ bit_nr = ((long)(*ntf_q_pp) - (long) ¬ify_buffer[0]) / sizeof(struct notification); *ntf_q_pp = (*ntf_q_pp)->n_next;/* remove from queue */ free_bit(bit_nr, notify_bitmap, NR_NOTIFY_BUFS); - kinfo.nr_ntf_pending --; return(OK); /* report success */ } ntf_q_pp = &(*ntf_q_pp)->n_next; /* proceed to next */ } } - /* No suitable message is available. Block the process trying to receive, - * unless this is not allowed by the system call. + /* No suitable message is available or the caller couldn't send in BOTH. + * Block the process trying to receive, unless the flags tell otherwise. */ - if (may_block) { + if (flags) { caller_ptr->p_getfrom = src; caller_ptr->p_messbuf = m_ptr; if (caller_ptr->p_flags == 0) unready(caller_ptr); @@ -316,51 +346,53 @@ message *m_ptr; /* pointer to message buffer */ int ntf_index; message ntf_mess; - /* Check to see if target is blocked waiting for this message. */ + /* Check to see if target is blocked waiting for this message. A process + * can be both sending and receiving during a BOTH system call. + */ if ( (dst_ptr->p_flags & (RECEIVING | SENDING)) == RECEIVING && - (dst_ptr->p_getfrom == ANY || - dst_ptr->p_getfrom == proc_number(caller_ptr))) { + (dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) { /* Destination is indeed waiting for this message. */ - CopyMess(proc_number(caller_ptr), caller_ptr, m_ptr, dst_ptr, - dst_ptr->p_messbuf); + CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr, + dst_ptr, dst_ptr->p_messbuf); dst_ptr->p_flags &= ~RECEIVING; /* deblock destination */ if (dst_ptr->p_flags == 0) ready(dst_ptr); } /* Destination is not ready. Add the notification to the pending queue. */ else { - /* Get pointer to notification message. */ - if (! istaskp(caller_ptr)) { - CopyMess(proc_number(caller_ptr), caller_ptr, m_ptr, + /* Get pointer to notification message. Don't copy for kernel. */ + if (! iskernelp(caller_ptr)) { + CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr, proc_addr(HARDWARE), &ntf_mess); m_ptr = &ntf_mess; } - /* Enqueue the message. Existing notifications are overwritten with - * the newer one. New notifications are added to the end of the list. + /* Enqueue the message. Existing notifications with the same source + * and type are overwritten with newer ones. New notifications that + * are not yet on the list are added to the end. */ ntf_q_pp = &dst_ptr->p_ntf_q; - while (*ntf_q_pp) { + while (*ntf_q_pp != NULL) { /* Replace notifications with same source and type. */ - if ((*ntf_q_pp)->n_type == m_ptr->m_type && - (*ntf_q_pp)->n_source == m_ptr->m_source) { + if ((*ntf_q_pp)->n_type == m_ptr->NOTIFY_TYPE && + (*ntf_q_pp)->n_source == proc_nr(caller_ptr)) { (*ntf_q_pp)->n_flags = m_ptr->NOTIFY_FLAGS; (*ntf_q_pp)->n_arg = m_ptr->NOTIFY_ARG; - break; + return(OK); } - return(OK); + ntf_q_pp = &(*ntf_q_pp)->n_next; } /* Add to end of queue. Get a free notification buffer. */ - if ((ntf_index = alloc_bit(notify_bitmap, NR_NOTIFY_BUFS)) < 0) - return(ENOSPC); /* should be atomic! */ - kinfo.nr_ntf_pending ++; + if ((ntf_index = alloc_bit(notify_bitmap, NR_NOTIFY_BUFS)) < 0) + return(ENOSPC); ntf_p = ¬ify_buffer[ntf_index]; - ntf_p->n_source = proc_number(caller_ptr); + ntf_p->n_source = proc_nr(caller_ptr); ntf_p->n_type = m_ptr->NOTIFY_TYPE; ntf_p->n_flags = m_ptr->NOTIFY_FLAGS; ntf_p->n_arg = m_ptr->NOTIFY_ARG; - *ntf_q_pp = ntf_p; + *ntf_q_pp = ntf_p; /* add to end of queue */ + ntf_p->n_next = NULL; /* mark new end of queue */ } return(OK); } @@ -374,16 +406,13 @@ message *m_ptr; /* pointer to message buffer */ { /* Safe gateway to mini_notify() for tasks and interrupt handlers. This * function checks if it is called from an interrupt handler and makes sure - * that the correct message source is put on the notification. All kernel - * generated notifications share the same pseudo-process number, to prevent - * conflicts with SENDREC calls to the kernel task. + * that the correct message source is put on the notification. */ int result; struct proc *caller_ptr; lock(); - caller_ptr = (k_reenter >= 0 || istaskp(proc_ptr)) ? - proc_addr(KERNEL) : proc_ptr; + caller_ptr = (k_reenter >= 0) ? proc_addr(HARDWARE) : proc_ptr; result = mini_notify(caller_ptr, dst, m_ptr); unlock(); return(result); @@ -423,6 +452,7 @@ register struct proc *rp; /* this process is now runnable */ { /* Add 'rp' to one of the queues of runnable processes. */ register int q = rp->p_priority; /* scheduling queue to use */ + register struct proc **xpp; /* iterate over queue */ #if ENABLE_K_DEBUGGING if(rp->p_ready) { @@ -435,6 +465,18 @@ register struct proc *rp; /* this process is now runnable */ * user processes are added in front of the queue, because this is a bit * fairer to I/O bound processes. */ +#if NEW_SCHED_Q + if (isuserp(rp)) { /* add to front of queue */ + rp->p_nextready = rdy_head[q]; /* chain current front */ + rdy_head[q] = rp; /* ready process becomes front */ + } + else { /* add to end of queue */ + xpp = &rdy_head[q]; /* find pointer to end of queue */ + while (*xpp != NIL_PROC) xpp = &(*xpp)->p_nextready; + *xpp = rp; /* replace end with ready process */ + 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; @@ -449,6 +491,7 @@ register struct proc *rp; /* this process is now runnable */ rdy_tail[q] = rp; rp->p_nextready = NIL_PROC; } +#endif /* 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 @@ -456,10 +499,6 @@ register struct proc *rp; /* this process is now runnable */ */ if (next_ptr && next_ptr->p_priority > rp->p_priority) next_ptr = rp; else if (proc_ptr->p_priority > rp->p_priority) next_ptr = rp; - -#if DEAD_CODE - if (rp->p_priority < proc_ptr->p_priority) proc_ptr = rp; -#endif } /*===========================================================================* @@ -470,9 +509,13 @@ register struct proc *rp; /* this process is no longer runnable */ { /* A process has blocked. See ready for a description of the queues. */ - register struct proc *xp; - register struct proc **qtail; /* queue's rdy_tail */ register int q = rp->p_priority; /* queue to use */ +#if NEW_SCHED_Q + register struct proc **xpp; /* iterate over queue */ +#else + register struct proc **qtail; /* queue's rdy_tail */ + register struct proc *xp; +#endif #if ENABLE_K_DEBUGGING if(!rp->p_ready) { @@ -484,13 +527,25 @@ register struct proc *rp; /* this process is no longer runnable */ /* Side-effect for tasks: check if the task's stack still is ok? */ if (istaskp(rp)) { if (*rp->p_stguard != STACK_GUARD) - panic("stack overrun by task", proc_number(rp)); + panic("stack overrun by task", proc_nr(rp)); } /* Now make sure that the process is not in its ready queue. Remove the * 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. */ +#if NEW_SCHED_Q + xpp = &rdy_head[q]; + while (*xpp != NIL_PROC) { /* check entire queue */ + if (*xpp == rp) { /* lookup unready process */ + *xpp = (*xpp)->p_nextready; /* replace it with next */ + if (rp == proc_ptr || rp == next_ptr) /* current process removed */ + pick_proc(); /* pick new process to run */ + break; + } + xpp = &(*xpp)->p_nextready; /* proceed to next */ + } +#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 */ @@ -508,25 +563,41 @@ register struct proc *rp; /* this process is no longer runnable */ rdy_tail[q] = xp; } } +#endif } /*===========================================================================* * sched * *===========================================================================*/ -PRIVATE void sched() +PRIVATE void sched(queue) +int queue; { /* 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, * possibly promoting another user to head of the queue. */ - if (rdy_head[PPRI_USER] == NIL_PROC) return; + register struct proc **xpp; + register struct proc *xp; + + if (rdy_head[queue] == NIL_PROC) return; /* One or more user processes queued. */ - rdy_tail[PPRI_USER]->p_nextready = rdy_head[PPRI_USER]; - rdy_tail[PPRI_USER] = rdy_head[PPRI_USER]; - rdy_head[PPRI_USER] = rdy_head[PPRI_USER]->p_nextready; - rdy_tail[PPRI_USER]->p_nextready = NIL_PROC; +#if NEW_SCHED_Q + + xp = rdy_head[queue]; /* save expired process */ + 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 end of queue */ + +#else + rdy_tail[queue]->p_nextready = rdy_head[queue]; + rdy_tail[queue] = rdy_head[queue]; + rdy_head[queue] = rdy_head[queue]->p_nextready; + rdy_tail[queue]->p_nextready = NIL_PROC; +#endif pick_proc(); } @@ -585,11 +656,12 @@ struct proc *rp; /* this process is no longer runnable */ /*==========================================================================* * lock_sched * *==========================================================================*/ -PUBLIC void lock_sched() +PUBLIC void lock_sched(queue) +int queue; { /* Safe gateway to sched() for tasks. */ lock(); - sched(); + sched(queue); unlock(); } diff --git a/kernel/proc.h b/kernel/proc.h index dba134665..19363d2c0 100755 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -35,7 +35,7 @@ struct proc { struct mem_map p_memmap[NR_LOCAL_SEGS]; /* local memory map (T, D, S) */ struct far_mem p_farmem[NR_REMOTE_SEGS]; /* remote memory map */ - short p_flags; /* SENDING, RECEIVING, etc. */ + char p_flags; /* SENDING, RECEIVING, etc. */ char p_type; /* task, system, driver, server, user, idle */ char p_priority; /* scheduling priority */ @@ -51,7 +51,7 @@ struct proc { struct proc *p_nextready; /* pointer to next ready process */ struct notification *p_ntf_q; /* queue of pending notifications */ struct proc *p_caller_q; /* head of list of procs wishing to send */ - struct proc *p_sendlink; /* link to next proc wishing to send */ + struct proc *p_q_link; /* link to next proc wishing to send */ message *p_messbuf; /* pointer to message buffer */ proc_nr_t p_getfrom; /* from whom does process want to receive? */ proc_nr_t p_sendto; /* to whom does process want to send? */ @@ -74,9 +74,9 @@ struct proc { #define NO_MAP 0x01 /* keeps unmapped forked child from running */ #define SENDING 0x02 /* set when process blocked trying to send */ #define RECEIVING 0x04 /* set when process blocked trying to recv */ -#define PENDING 0x08 /* set when inform() of signal pending */ -#define SIG_PENDING 0x10 /* keeps to-be-signalled proc from running */ -#define P_STOP 0x20 /* set when process is being traced */ +#define PENDING 0x10 /* set when inform() of signal pending */ +#define SIG_PENDING 0x20 /* keeps to-be-signalled proc from running */ +#define P_STOP 0x40 /* set when process is being traced */ /* Values for p_type. Non-negative values represent active process types. * Process types are important to model inter-process relationships. When @@ -120,9 +120,6 @@ struct proc { #define isalive(n) (proc_addr(n)->p_type > P_NONE) #define isalivep(p) ((p)->p_type > P_NONE) #define isrxhardware(n) ((n) == ANY || (n) == HARDWARE) -#define iskernel(n) ((n) == CLOCK || (n) == SYSTASK) -#define issysentn(n) ((n) == FS_PROC_NR || (n) == PM_PROC_NR) -#define issysentp(p) (issysentn((p)->p_nr)) #define isreservedp(p) ((p)->p_type == P_RESERVED) #define isemptyp(p) ((p)->p_type == P_NONE) #define istaskp(p) ((p)->p_type == P_TASK) @@ -131,12 +128,11 @@ struct proc { #define isuserp(p) ((p)->p_type == P_USER) #define isuser(n) (proc_addr(n)->p_type == P_USER) #define isidlep(p) ((p)->p_type == P_IDLE) -#define proc_addr(n) (pproc_addr + NR_TASKS)[(n)] #define cproc_addr(n) (&(proc + NR_TASKS)[(n)]) -#define proc_number(p) ((p)->p_nr) -#define proc_vir2phys(p, vir) \ - (((phys_bytes)(p)->p_map[D].mem_phys << CLICK_SHIFT) \ - + (vir_bytes) (vir)) +#define proc_addr(n) (pproc_addr + NR_TASKS)[(n)] +#define proc_nr(p) ((p)->p_nr) +#define iskernelp(p) ((p)->p_nr < 0) +#define iskernel(n) ((n) == CLOCK || (n) == SYSTASK) /* The process table and pointers to process table slots. The pointers allow * faster access because now a process entry can be found by indexing the diff --git a/kernel/proto.h b/kernel/proto.h index e3db8c437..79ee9b27f 100755 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -48,7 +48,7 @@ _PROTOTYPE( int lock_notify, (int dst, message *m_ptr) ); _PROTOTYPE( int lock_send, (int dst, message *m_ptr) ); _PROTOTYPE( void lock_pick_proc, (void) ); _PROTOTYPE( void lock_ready, (struct proc *rp) ); -_PROTOTYPE( void lock_sched, (void) ); +_PROTOTYPE( void lock_sched, (int queue) ); _PROTOTYPE( void lock_unready, (struct proc *rp) ); /* start.c */ diff --git a/kernel/system.c b/kernel/system.c index 1dff3a21c..a1dc3ec83 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -79,7 +79,7 @@ PUBLIC void sys_task() if ((unsigned) m.m_type < NR_SYS_CALLS) { result = (*call_vec[m.m_type])(&m); /* do system call */ } else { - kprintf("SYS task got illegal request from %d.\n", m.m_source); + kprintf("Warning, illegal SYSTASK request from %d.\n", m.m_source); result = EBADREQUEST; /* illegal message type */ } @@ -89,7 +89,8 @@ PUBLIC void sys_task() */ if (result != EDONTREPLY) { m.m_type = result; /* report status of call */ - lock_send(m.m_source, &m); + if (OK != lock_send(m.m_source, &m)) + kprintf("Warning, SYSTASK couldn't reply to %d\n", m.m_source); } } } @@ -177,7 +178,11 @@ PUBLIC void clear_proc(proc_nr) int proc_nr; /* slot of process to clean up */ { register struct proc *rp, *rc; +#if DEAD_CODE struct proc *np, *xp; +#else + register struct proc **xpp; /* iterate over caller queue */ +#endif /* Get a pointer to the process that exited. */ rc = proc_addr(proc_nr); @@ -199,22 +204,34 @@ int proc_nr; /* slot of process to clean up */ /* Check all proc slots to see if the exiting process is queued. */ for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) { if (rp->p_caller_q == NIL_PROC) continue; +#if DEAD_CODE if (rp->p_caller_q == rc) { /* Exiting process is on front of this queue. */ - rp->p_caller_q = rc->p_sendlink; + rp->p_caller_q = rc->p_q_link; break; } else { /* See if exiting process is in middle of queue. */ np = rp->p_caller_q; - while ( ( xp = np->p_sendlink) != NIL_PROC) { + while ( ( xp = np->p_q_link) != NIL_PROC) { if (xp == rc) { - np->p_sendlink = xp->p_sendlink; + np->p_q_link = xp->p_q_link; break; } else { np = xp; } } } +#else + /* Make sure that the exiting process is not on the queue. */ + xpp = &rp->p_caller_q; + while (*xpp != NIL_PROC) { /* check entire queue */ + if (*xpp == rc) { /* process is on the queue */ + *xpp = (*xpp)->p_q_link; /* replace by next process */ + break; + } + xpp = &(*xpp)->p_q_link; /* proceed to next queued */ + } +#endif } } diff --git a/kernel/system/clock.c b/kernel/system/clock.c index 46a7ab988..328f3f8f1 100644 --- a/kernel/system/clock.c +++ b/kernel/system/clock.c @@ -165,7 +165,6 @@ timer_t *tp; * process given with a SYN_ALARM message. */ message m; - m.NOTIFY_SOURCE = SYSTASK; m.NOTIFY_TYPE = SYN_ALARM; m.NOTIFY_ARG = get_uptime(); m.NOTIFY_FLAGS = 0; diff --git a/kernel/system/sigctl.c b/kernel/system/sigctl.c index e154a8250..21e0b04bc 100644 --- a/kernel/system/sigctl.c +++ b/kernel/system/sigctl.c @@ -35,7 +35,7 @@ message *m_ptr; /* pointer to request message */ /* Find the next process with pending signals. */ for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) { if (rp->p_flags & PENDING) { - m_ptr->SIG_PROC = proc_number(rp); + m_ptr->SIG_PROC = rp->p_nr; m_ptr->SIG_MAP = rp->p_pending; sigemptyset(&rp->p_pending); /* ball is in PM's court */ rp->p_flags &= ~PENDING; /* blocked by SIG_PENDING */ diff --git a/kernel/table.c b/kernel/table.c index 60a1205da..d4d274bac 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -67,11 +67,11 @@ PUBLIC struct system_image image[] = { { HARDWARE, 0, P_TASK, PPRI_TASK, HARDWARE_STACK,HARDWARE_SENDMASK,"HARDWAR" }, { PM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, PM_SENDMASK, "PM" }, { FS_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, FS_SENDMASK, "FS" }, - { IS_PROC_NR, 0, P_SYSTEM, PPRI_HIGHER, 0, IS_SENDMASK, "IS" }, + { IS_PROC_NR, 0, P_SYSTEM, PPRI_HIGH, 0, IS_SENDMASK, "IS" }, { TTY, 0, P_SYSTEM, PPRI_HIGHER, 0, TTY_SENDMASK, "TTY" }, { MEMORY, 0, P_DRIVER, PPRI_HIGH, 0, MEM_SENDMASK, "MEMORY" }, #if ENABLE_AT_WINI - { AT_WINI, 0, P_DRIVER, PPRI_HIGHER, 0, AT_SENDMASK, "AT_WINI" }, + { AT_WINI, 0, P_DRIVER, PPRI_HIGH, 0, AT_SENDMASK, "AT_WINI" }, #endif #if ENABLE_FLOPPY { FLOPPY, 0, P_DRIVER, PPRI_HIGH, 0, FLOPPY_SENDMASK, "FLOPPY" }, diff --git a/servers/is/dmp.c b/servers/is/dmp.c index 5ec2923cc..5e23037c0 100644 --- a/servers/is/dmp.c +++ b/servers/is/dmp.c @@ -51,8 +51,13 @@ struct system_image image[IMAGE_SIZE]; *===========================================================================*/ PUBLIC int do_fkey_pressed(message *m) { +#if DEAD_CODE if (F1 <= m->FKEY_CODE && m->FKEY_CODE <= F12) { switch(m->FKEY_CODE) { +#else + if (F1 <= m->NOTIFY_ARG && m->NOTIFY_ARG <= F12) { + switch(m->NOTIFY_ARG) { +#endif case F1: proctab_dmp(); break; case F2: memmap_dmp(); break; case F3: image_dmp(); break; @@ -65,7 +70,12 @@ PUBLIC int do_fkey_pressed(message *m) case F11: memchunks_dmp(); break; case F12: sched_dmp(); break; default: +#if DEAD_CODE printf("IS: unhandled notification for F%d\n", m->FKEY_NUM); +#else + printf("IS: unhandled notify for F%d (code %d)\n", + m->NOTIFY_ARG, m->NOTIFY_FLAGS); +#endif } } return(EDONTREPLY); @@ -376,7 +386,7 @@ PRIVATE void sendmask_dmp() printf("\n\n"); printf(" "); - for (j=proc_number(BEG_PROC_ADDR); j< INIT_PROC_NR+1; j++) { + for (j=proc_nr(BEG_PROC_ADDR); j< INIT_PROC_NR+1; j++) { printf("%3d", j); } printf(" *\n"); @@ -386,17 +396,17 @@ PRIVATE void sendmask_dmp() if (++n > 20) break; printf("%8s ", rp->p_name); - j = proc_number(rp); + j = proc_nr(rp); switch(rp->p_type) { - case P_IDLE: printf("/%3d/ ", proc_number(rp)); break; - case P_TASK: printf("[%3d] ", proc_number(rp)); break; - case P_SYSTEM: printf("<%3d> ", proc_number(rp)); break; - case P_DRIVER: printf("{%3d} ", proc_number(rp)); break; - case P_SERVER: printf("(%3d) ", proc_number(rp)); break; - default: printf(" %3d ", proc_number(rp)); + case P_IDLE: printf("/%3d/ ", proc_nr(rp)); break; + case P_TASK: printf("[%3d] ", proc_nr(rp)); break; + case P_SYSTEM: printf("<%3d> ", proc_nr(rp)); break; + case P_DRIVER: printf("{%3d} ", proc_nr(rp)); break; + case P_SERVER: printf("(%3d) ", proc_nr(rp)); break; + default: printf(" %3d ", proc_nr(rp)); } - for (j=proc_number(BEG_PROC_ADDR); jp_sendmask, j)) printf(" 1 "); else printf(" 0 "); } @@ -438,12 +448,12 @@ PRIVATE void proctab_dmp() size = rp->p_memmap[T].mem_len + ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len) - data); switch(rp->p_type) { - case P_IDLE: printf("/%3d/ ", proc_number(rp)); break; - case P_TASK: printf("[%3d] ", proc_number(rp)); break; - case P_SYSTEM: printf("<%3d> ", proc_number(rp)); break; - case P_DRIVER: printf("{%3d} ", proc_number(rp)); break; - case P_SERVER: printf("(%3d) ", proc_number(rp)); break; - default: printf(" %3d ", proc_number(rp)); + case P_IDLE: printf("/%3d/ ", proc_nr(rp)); break; + case P_TASK: printf("[%3d] ", proc_nr(rp)); break; + case P_SYSTEM: printf("<%3d> ", proc_nr(rp)); break; + case P_DRIVER: printf("{%3d} ", proc_nr(rp)); break; + case P_SERVER: printf("(%3d) ", proc_nr(rp)); break; + default: printf(" %3d ", proc_nr(rp)); } printf("%3u %7lx%7lx %6lu%6lu%6uK%6uK%6uK %3x", rp->p_priority, @@ -493,7 +503,7 @@ PRIVATE void memmap_dmp() + ((rp->p_memmap[S].mem_phys + rp->p_memmap[S].mem_len) - rp->p_memmap[D].mem_phys); printf("%3d %-7.7s %4x %4x %4x %4x %4x %4x %4x %4x %4x %5uK\n", - proc_number(rp), + proc_nr(rp), rp->p_name, rp->p_memmap[T].mem_vir, rp->p_memmap[T].mem_phys, rp->p_memmap[T].mem_len, rp->p_memmap[D].mem_vir, rp->p_memmap[D].mem_phys, rp->p_memmap[D].mem_len,