From: Ben Gras Date: Wed, 10 Mar 2010 13:00:05 +0000 (+0000) Subject: re-establish kernel assert()s. X-Git-Tag: v3.1.7~242 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=0937d6c3677085c5a30c85a51ddef5b29a25f81c;p=minix.git re-establish kernel assert()s. use the regular assert() instead of vmassert() in kernel. throw out some #if 0 code. fix a few assert() conditions. enable by default. --- diff --git a/kernel/arch/i386/exception.c b/kernel/arch/i386/exception.c index 004b67a05..7e9538300 100644 --- a/kernel/arch/i386/exception.c +++ b/kernel/arch/i386/exception.c @@ -7,6 +7,7 @@ #include "proto.h" #include #include +#include #include "../../proc.h" #include "../../proto.h" @@ -21,7 +22,7 @@ void pagefault( struct proc *pr, reg_t pagefaultcr2; - vmassert(frame); + assert(frame); pagefaultcr2 = read_cr2(); @@ -31,7 +32,7 @@ void pagefault( struct proc *pr, #endif if(pr->p_seg.p_cr3) { - vmassert(pr->p_seg.p_cr3 == read_cr3()); + assert(pr->p_seg.p_cr3 == read_cr3()); } in_physcopy = (frame->eip > (vir_bytes) phys_copy) && @@ -76,8 +77,8 @@ void pagefault( struct proc *pr, } /* Don't schedule this process until pagefault is handled. */ - vmassert(pr->p_seg.p_cr3 == read_cr3()); - vmassert(!RTS_ISSET(pr, RTS_PAGEFAULT)); + assert(pr->p_seg.p_cr3 == read_cr3()); + assert(!RTS_ISSET(pr, RTS_PAGEFAULT)); RTS_SET(pr, RTS_PAGEFAULT); /* Save pagefault details, suspend process, diff --git a/kernel/arch/i386/memory.c b/kernel/arch/i386/memory.c index dc05c8c78..1a6b2e11a 100644 --- a/kernel/arch/i386/memory.c +++ b/kernel/arch/i386/memory.c @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -50,6 +51,7 @@ PUBLIC void vm_init(struct proc *newptproc) if(vm_running) panic("vm_init: vm_running"); switch_address_space(newptproc); + assert(ptproc == newptproc); vm_enable_paging(); vm_running = 1; @@ -85,11 +87,11 @@ PUBLIC void vm_init(struct proc *newptproc) int mustinvl; \ u32_t pdeval, mask; \ phys_bytes offset; \ - vmassert(psok); \ + assert(psok); \ if(PROC) { \ TYPE = TYPEPROCMAP; \ - vmassert(!iskernelp(PROC)); \ - vmassert(HASPT(PROC)); \ + assert(!iskernelp(PROC)); \ + assert(HASPT(PROC)); \ pdeptr = PROCPDEPTR(PROC, proc_pde_index); \ pdeval = *pdeptr; \ } else { \ @@ -104,15 +106,15 @@ PUBLIC void vm_init(struct proc *newptproc) continue; \ *PROCPDEPTR(ptproc, k) = 0; \ PDE = k; \ - vmassert(k >= 0); \ - vmassert(k < sizeof(dirtypde)*8); \ + assert(k >= 0); \ + assert(k < sizeof(dirtypde)*8); \ mask = PDEMASK(PDE); \ if(dirtypde & mask) \ continue; \ break; \ } \ - vmassert(PDE != NOPDE); \ - vmassert(mask); \ + assert(PDE != NOPDE); \ + assert(mask); \ if(dirtypde & mask) { \ mustinvl = TRUE; \ } else { \ @@ -131,16 +133,16 @@ PUBLIC void vm_init(struct proc *newptproc) #define DONEPDE(PDE) { \ if(PDE != NOPDE) { \ - vmassert(PDE > 0); \ - vmassert(PDE < sizeof(dirtypde)*8); \ + assert(PDE > 0); \ + assert(PDE < sizeof(dirtypde)*8); \ dirtypde |= PDEMASK(PDE); \ } \ } #define WIPEPDE(PDE) { \ if(PDE != NOPDE) { \ - vmassert(PDE > 0); \ - vmassert(PDE < sizeof(dirtypde)*8); \ + assert(PDE > 0); \ + assert(PDE < sizeof(dirtypde)*8); \ *PROCPDEPTR(ptproc, PDE) = 0; \ } \ } @@ -156,16 +158,16 @@ PRIVATE int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr, NOREC_ENTER(linlincopy); - vmassert(vm_running); - vmassert(nfreepdes >= 3); + assert(vm_running); + assert(nfreepdes >= 3); - vmassert(ptproc); - vmassert(proc_ptr); - vmassert(getcr3val() == ptproc->p_seg.p_cr3); + assert(ptproc); + assert(proc_ptr); + assert(read_cr3() == ptproc->p_seg.p_cr3); procslot = ptproc->p_nr; - vmassert(procslot >= 0 && procslot < I386_VM_DIR_ENTRIES); + assert(procslot >= 0 && procslot < I386_VM_DIR_ENTRIES); while(bytes > 0) { phys_bytes srcptr, dstptr; @@ -434,7 +436,7 @@ vir_bytes bytes; /* # of bytes to be copied */ /* phys must be larger than 0 (or the caller will think the call * failed), and address must not cross a page boundary. */ - vmassert(phys); + assert(phys); return phys; } @@ -450,9 +452,9 @@ PUBLIC int vm_lookup(struct proc *proc, vir_bytes virtual, vir_bytes *physical, u32_t pde_v, pte_v; NOREC_ENTER(vmlookup); - vmassert(proc); - vmassert(physical); - vmassert(!isemptyp(proc)); + assert(proc); + assert(physical); + assert(!isemptyp(proc)); if(!HASPT(proc)) { *physical = virtual; @@ -461,9 +463,9 @@ PUBLIC int vm_lookup(struct proc *proc, vir_bytes virtual, vir_bytes *physical, /* Retrieve page directory entry. */ root = (u32_t *) proc->p_seg.p_cr3; - vmassert(!((u32_t) root % I386_PAGE_SIZE)); + assert(!((u32_t) root % I386_PAGE_SIZE)); pde = I386_VM_PDE(virtual); - vmassert(pde >= 0 && pde < I386_VM_DIR_ENTRIES); + assert(pde >= 0 && pde < I386_VM_DIR_ENTRIES); pde_v = phys_get32((u32_t) (root + pde)); if(!(pde_v & I386_VM_PRESENT)) { @@ -478,9 +480,9 @@ PUBLIC int vm_lookup(struct proc *proc, vir_bytes virtual, vir_bytes *physical, } else { /* Retrieve page table entry. */ pt = (u32_t *) I386_VM_PFA(pde_v); - vmassert(!((u32_t) pt % I386_PAGE_SIZE)); + assert(!((u32_t) pt % I386_PAGE_SIZE)); pte = I386_VM_PTE(virtual); - vmassert(pte >= 0 && pte < I386_VM_PT_ENTRIES); + assert(pte >= 0 && pte < I386_VM_PT_ENTRIES); pte_v = phys_get32((u32_t) (pt + pte)); if(!(pte_v & I386_VM_PRESENT)) { NOREC_RETURN(vmlookup, EFAULT); @@ -505,8 +507,8 @@ PUBLIC int vm_contiguous(struct proc *targetproc, u32_t vir_buf, size_t bytes) u32_t prev_phys = 0; /* Keep lints happy. */ u32_t po; - vmassert(targetproc); - vmassert(bytes > 0); + assert(targetproc); + assert(bytes > 0); if(!HASPT(targetproc)) return 1; @@ -561,16 +563,11 @@ PRIVATE void vm_suspend(struct proc *caller, struct proc *target, /* This range is not OK for this process. Set parameters * of the request and notify VM about the pending request. */ - vmassert(!RTS_ISSET(caller, RTS_VMREQUEST)); - vmassert(!RTS_ISSET(target, RTS_VMREQUEST)); + assert(!RTS_ISSET(caller, RTS_VMREQUEST)); + assert(!RTS_ISSET(target, RTS_VMREQUEST)); RTS_SET(caller, RTS_VMREQUEST); -#if DEBUG_VMASSERT - caller->p_vmrequest.stacktrace[0] = '\0'; - util_stacktrace_strcat(caller->p_vmrequest.stacktrace); -#endif - caller->p_vmrequest.req_type = VMPTYPE_CHECK; caller->p_vmrequest.target = target->p_endpoint; caller->p_vmrequest.params.check.start = linaddr; @@ -593,20 +590,11 @@ int delivermsg(struct proc *rp) int r; NOREC_ENTER(deliver); - vmassert(rp->p_misc_flags & MF_DELIVERMSG); - vmassert(rp->p_delivermsg.m_source != NONE); - - vmassert(rp->p_delivermsg_lin); -#if DEBUG_VMASSERT - if(rp->p_delivermsg_lin != - umap_local(rp, D, rp->p_delivermsg_vir, sizeof(message))) { - printf("vir: 0x%lx lin was: 0x%lx umap now: 0x%lx\n", - rp->p_delivermsg_vir, rp->p_delivermsg_lin, - umap_local(rp, D, rp->p_delivermsg_vir, sizeof(message))); - panic("that's wrong"); - } + assert(rp->p_misc_flags & MF_DELIVERMSG); + assert(rp->p_delivermsg.m_source != NONE); -#endif + assert(rp->p_delivermsg_lin); + assert(rp->p_delivermsg_lin == umap_local(rp, D, rp->p_delivermsg_vir, sizeof(message))); PHYS_COPY_CATCH(vir2phys(&rp->p_delivermsg), rp->p_delivermsg_lin, sizeof(message), addr); @@ -616,10 +604,10 @@ int delivermsg(struct proc *rp) VMSTYPE_DELIVERMSG); r = VMSUSPEND; } else { -#if DEBUG_VMASSERT + /* Indicate message has been delivered; address is 'used'. */ rp->p_delivermsg.m_source = NONE; rp->p_delivermsg_lin = 0; -#endif + rp->p_misc_flags &= ~MF_DELIVERMSG; r = OK; } @@ -649,7 +637,7 @@ PRIVATE void vm_pt_print(u32_t *pagetable, u32_t v) int pte; int col = 0; - vmassert(!((u32_t) pagetable % I386_PAGE_SIZE)); + assert(!((u32_t) pagetable % I386_PAGE_SIZE)); for(pte = 0; pte < I386_VM_PT_ENTRIES; pte++) { u32_t pte_v, pfa; @@ -672,7 +660,7 @@ PRIVATE void vm_print(u32_t *root) { int pde; - vmassert(!((u32_t) root % I386_PAGE_SIZE)); + assert(!((u32_t) root % I386_PAGE_SIZE)); printf("page table 0x%lx:\n", root); @@ -713,7 +701,7 @@ int vm_phys_memset(phys_bytes ph, u8_t c, phys_bytes bytes) NOREC_RETURN(physmemset, OK); } - vmassert(nfreepdes >= 3); + assert(nfreepdes >= 3); /* With VM, we have to map in the physical memory. * We can do this 4MB at a time. @@ -757,7 +745,7 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */ struct proc *procs[2]; NOREC_ENTER(virtualcopy); - vmassert((vmcheck && caller) || (!vmcheck && !caller)); + assert((vmcheck && caller) || (!vmcheck && !caller)); /* Check copy count. */ if (bytes <= 0) return(EDOM); @@ -831,13 +819,9 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */ int r; if(caller && RTS_ISSET(caller, RTS_VMREQUEST)) { - vmassert(caller->p_vmrequest.vmresult != VMSUSPEND); + assert(caller->p_vmrequest.vmresult != VMSUSPEND); RTS_UNSET(caller, RTS_VMREQUEST); if(caller->p_vmrequest.vmresult != OK) { -#if DEBUG_VMASSERT - printf("virtual_copy: returning VM error %d\n", - caller->p_vmrequest.vmresult); -#endif NOREC_RETURN(virtualcopy, caller->p_vmrequest.vmresult); } } @@ -852,7 +836,7 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */ NOREC_RETURN(virtualcopy, r); } - vmassert(procs[_SRC_] && procs[_DST_]); + assert(procs[_SRC_] && procs[_DST_]); if(r == EFAULT_SRC) { lin = phys_addr[_SRC_]; @@ -864,22 +848,14 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */ panic("r strange: %d", r); } -#if 0 - printf("virtual_copy: suspending caller %d / %s, target %d / %s\n", - caller->p_endpoint, caller->p_name, - target->p_endpoint, target->p_name); -#endif - - vmassert(proc_ptr->p_endpoint == SYSTEM); - vm_suspend(caller, target, lin, bytes, - VMSTYPE_KERNELCALL); + vm_suspend(caller, target, lin, bytes, VMSTYPE_KERNELCALL); NOREC_RETURN(virtualcopy, VMSUSPEND); } NOREC_RETURN(virtualcopy, OK); } - vmassert(!vm_running); + assert(!vm_running); /* can't copy to/from process with PT without VM */ #define NOPT(p) (!(p) || !HASPT(p)) diff --git a/kernel/debug.c b/kernel/debug.c index 407a8ebfd..89d430fc8 100644 --- a/kernel/debug.c +++ b/kernel/debug.c @@ -11,97 +11,101 @@ #include #include -#if DEBUG_SCHED_CHECK /* only include code if enabled */ - #define MAX_LOOP (NR_PROCS + NR_TASKS) -PUBLIC void -check_runqueues_f(char *file, int line) +PUBLIC int +runqueues_ok(void) { int q, l = 0; register struct proc *xp; - FIXME("check_runqueues being done"); - -#define MYPANIC(msg) { \ - panic("check_runqueues:%s:%d: %s\n", file, line, msg); \ - } - for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) { xp->p_found = 0; - if (l++ > MAX_LOOP) { MYPANIC("check error"); } + if (l++ > MAX_LOOP) panic("check error"); } for (q=l=0; q < NR_SCHED_QUEUES; q++) { if (rdy_head[q] && !rdy_tail[q]) { printf("head but no tail in %d\n", q); - MYPANIC("scheduling error"); + return 0; } if (!rdy_head[q] && rdy_tail[q]) { printf("tail but no head in %d\n", q); - MYPANIC("scheduling error"); + return 0; } if (rdy_tail[q] && rdy_tail[q]->p_nextready != NIL_PROC) { printf("tail and tail->next not null in %d\n", q); - MYPANIC("scheduling error"); + return 0; } for(xp = rdy_head[q]; xp != NIL_PROC; xp = xp->p_nextready) { vir_bytes vxp = (vir_bytes) xp, dxp; if(vxp < (vir_bytes) BEG_PROC_ADDR || vxp >= (vir_bytes) END_PROC_ADDR) { - MYPANIC("xp out of range"); + printf("xp out of range\n"); + return 0; } dxp = vxp - (vir_bytes) BEG_PROC_ADDR; if(dxp % sizeof(struct proc)) { - MYPANIC("xp not a real pointer"); + printf("xp not a real pointer"); + return 0; } - if(xp->p_magic != PMAGIC) { - MYPANIC("magic wrong in xp"); + if(!proc_ptr_ok(xp)) { + printf("xp bogus pointer"); + return 0; } if (RTS_ISSET(xp, RTS_SLOT_FREE)) { printf("scheduling error: dead proc q %d %d\n", q, xp->p_endpoint); - MYPANIC("dead proc on run queue"); + return 0; } - if (!xp->p_ready) { + if (!proc_is_runnable(xp)) { printf("scheduling error: unready on runq %d proc %d\n", q, xp->p_nr); - MYPANIC("found unready process on run queue"); + return 0; } if (xp->p_priority != q) { printf("scheduling error: wrong priority q %d proc %d ep %d name %s\n", q, xp->p_nr, xp->p_endpoint, xp->p_name); - MYPANIC("wrong priority"); + return 0; } if (xp->p_found) { printf("scheduling error: double sched q %d proc %d\n", q, xp->p_nr); - MYPANIC("proc more than once on scheduling queue"); + return 0; } xp->p_found = 1; if (xp->p_nextready == NIL_PROC && rdy_tail[q] != xp) { printf("sched err: last element not tail q %d proc %d\n", q, xp->p_nr); - MYPANIC("scheduling error"); + return 0; + } + if (l++ > MAX_LOOP) { + printf("loop in schedule queue?"); + return 0; } - if (l++ > MAX_LOOP) MYPANIC("loop in schedule queue?"); } } l = 0; for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) { - if(xp->p_magic != PMAGIC) - MYPANIC("p_magic wrong in proc table"); + if(!proc_ptr_ok(xp)) { + printf("xp bogus pointer in proc table\n"); + return 0; + } if (isemptyp(xp)) continue; - if(xp->p_ready && ! xp->p_found) { + if(proc_is_runnable(xp) && !xp->p_found) { printf("sched error: ready proc %d not on queue\n", xp->p_nr); - MYPANIC("ready proc not on scheduling queue"); - if (l++ > MAX_LOOP) { MYPANIC("loop in debug.c?"); } + return 0; + if (l++ > MAX_LOOP) { + printf("loop in debug.c?\n"); + return 0; + } } } -} -#endif /* DEBUG_SCHED_CHECK */ + /* All is ok. */ + return 1; +} PUBLIC char * rtsflagstr(int flags) diff --git a/kernel/debug.h b/kernel/debug.h index 52dd75cba..b8cddbd38 100644 --- a/kernel/debug.h +++ b/kernel/debug.h @@ -24,10 +24,10 @@ #define DEBUG_STACKTRACE 1 #define DEBUG_TIME_LOCKS 1 -/* Runtime sanity checking. */ -#define DEBUG_VMASSERT 0 -#define DEBUG_SCHED_CHECK 0 -#define DEBUG_STACK_CHECK 0 +/* Sanity checks. */ +#define DEBUG_SANITYCHECKS 0 + +/* Verbose messages. */ #define DEBUG_TRACE 0 #if DEBUG_TRACE @@ -46,25 +46,18 @@ #define NOREC_ENTER(varname) \ static int varname = NOTENTERED; \ - vmassert(varname == ENTERED || varname == NOTENTERED); \ - vmassert(magictest == MAGICTEST); \ - vmassert(varname != ENTERED); \ + assert(varname == ENTERED || varname == NOTENTERED); \ + assert(magictest == MAGICTEST); \ + assert(varname != ENTERED); \ varname = ENTERED; #define NOREC_RETURN(varname, v) do { \ - vmassert(magictest == MAGICTEST); \ - vmassert(varname == ENTERED || varname == NOTENTERED); \ + assert(magictest == MAGICTEST); \ + assert(varname == ENTERED || varname == NOTENTERED); \ varname = NOTENTERED; \ return v; \ } while(0) -#if DEBUG_VMASSERT -#define vmassert(t) { \ - if(!(t)) { panic("kernel:%s:%d: assert %s failed", __FILE__, __LINE__, #t); } } -#else -#define vmassert(t) { } -#endif - #define NOT_REACHABLE do { \ panic("NOT_REACHABLE at %s:%d", __FILE__, __LINE__); \ for(;;); \ diff --git a/kernel/main.c b/kernel/main.c index baa9d5f8b..450f5a704 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -11,6 +11,7 @@ #include "kernel.h" #include #include +#include #include #include #include @@ -48,9 +49,7 @@ PUBLIC void main() */ for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) { rp->p_rts_flags = RTS_SLOT_FREE; /* initialize free slot */ -#if DEBUG_SCHED_CHECK rp->p_magic = PMAGIC; -#endif rp->p_nr = i; /* proc number from ptr */ rp->p_endpoint = _ENDPOINT(0, rp->p_nr); /* generation no. 0 */ } @@ -251,12 +250,6 @@ PUBLIC void main() * so it's a clear warning no full release should be done with them * enabled. */ -#if DEBUG_SCHED_CHECK - FIXME("DEBUG_SCHED_CHECK enabled"); -#endif -#if DEBUG_VMASSERT - FIXME("DEBUG_VMASSERT enabled"); -#endif #if DEBUG_PROC_CHECK FIXME("PROC check enabled"); #endif @@ -265,6 +258,8 @@ PUBLIC void main() cycles_accounting_init(); DEBUGMAX(("done\n")); + assert(runqueues_ok()); + restart(); NOT_REACHABLE; } diff --git a/kernel/proc.c b/kernel/proc.c index e159945e5..bed06360d 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "debug.h" #include "kernel.h" @@ -86,9 +87,9 @@ PRIVATE int QueueMess(endpoint_t ep, vir_bytes msg_lin, struct proc *dst) * process (using dst process table entry). Do actual copy to * kernel here; it's an error if the copy fails into kernel. */ - vmassert(!(dst->p_misc_flags & MF_DELIVERMSG)); - vmassert(dst->p_delivermsg_lin); - vmassert(isokendpt(ep, &k)); + assert(!(dst->p_misc_flags & MF_DELIVERMSG)); + assert(dst->p_delivermsg_lin); + assert(isokendpt(ep, &k)); #if 0 if(INMEMORY(dst)) { @@ -184,13 +185,13 @@ not_runnable_pick_new: check_misc_flags: - vmassert(proc_ptr); - vmassert(proc_is_runnable(proc_ptr)); + assert(proc_ptr); + assert(proc_is_runnable(proc_ptr)); while (proc_ptr->p_misc_flags & (MF_KCALL_RESUME | MF_DELIVERMSG | MF_SC_DEFER | MF_SC_TRACE | MF_SC_ACTIVE)) { - vmassert(proc_is_runnable(proc_ptr)); + assert(proc_is_runnable(proc_ptr)); if (proc_ptr->p_misc_flags & MF_KCALL_RESUME) { kernel_call_resume(proc_ptr); } @@ -202,16 +203,13 @@ check_misc_flags: printf("suspending %s / %d\n", proc_ptr->p_name, proc_ptr->p_endpoint);); - vmassert(!proc_is_runnable(proc_ptr)); + assert(!proc_is_runnable(proc_ptr)); } } else if (proc_ptr->p_misc_flags & MF_SC_DEFER) { /* Perform the system call that we deferred earlier. */ -#if DEBUG_SCHED_CHECK - if (proc_ptr->p_misc_flags & MF_SC_ACTIVE) - panic("MF_SC_ACTIVE and MF_SC_DEFER set"); -#endif + assert (!(proc_ptr->p_misc_flags & MF_SC_ACTIVE)); arch_do_syscall(proc_ptr); @@ -286,6 +284,8 @@ long bit_map; /* notification event set or flags */ int src_dst_p; /* Process slot number */ size_t msg_size; + assert(!RTS_ISSET(caller_ptr, RTS_SLOT_FREE)); + /* If this process is subject to system call tracing, handle that first. */ if (caller_ptr->p_misc_flags & (MF_SC_TRACE | MF_SC_DEFER)) { /* Are we tracing this process, and is it the first sys_call entry? */ @@ -308,44 +308,16 @@ long bit_map; /* notification event set or flags */ /* If the MF_SC_DEFER flag is set, the syscall is now being resumed. */ caller_ptr->p_misc_flags &= ~MF_SC_DEFER; -#if DEBUG_SCHED_CHECK - if (caller_ptr->p_misc_flags & MF_SC_ACTIVE) - panic("MF_SC_ACTIVE already set"); -#endif + assert (!(caller_ptr->p_misc_flags & MF_SC_ACTIVE)); /* Set a flag to allow reliable tracing of leaving the system call. */ caller_ptr->p_misc_flags |= MF_SC_ACTIVE; } -#if DEBUG_SCHED_CHECK if(caller_ptr->p_misc_flags & MF_DELIVERMSG) { - printf("sys_call: MF_DELIVERMSG on for %s / %d\n", + panic("sys_call: MF_DELIVERMSG on for %s / %d\n", caller_ptr->p_name, caller_ptr->p_endpoint); - panic("MF_DELIVERMSG on"); - } -#endif - -#if 0 - if(src_dst_e != 4 && src_dst_e != 5 && - caller_ptr->p_endpoint != 4 && caller_ptr->p_endpoint != 5) { - if(call_nr == SEND) - printf("(%d SEND to %d) ", caller_ptr->p_endpoint, src_dst_e); - else if(call_nr == RECEIVE) - printf("(%d RECEIVE from %d) ", caller_ptr->p_endpoint, src_dst_e); - else if(call_nr == SENDREC) - printf("(%d SENDREC to %d) ", caller_ptr->p_endpoint, src_dst_e); - else - printf("(%d %d to/from %d) ", caller_ptr->p_endpoint, call_nr, src_dst_e); } -#endif - -#if DEBUG_SCHED_CHECK - if (RTS_ISSET(caller_ptr, RTS_SLOT_FREE)) - { - printf("called by the dead?!?\n"); - return EINVAL; - } -#endif /* Check destination. SENDA is special because its argument is a table and * not a single destination. RECEIVE is the only call that accepts ANY (in @@ -592,7 +564,7 @@ int flags; */ if (WILLRECEIVE(dst_ptr, caller_ptr->p_endpoint)) { /* Destination is indeed waiting for this message. */ - vmassert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG)); + assert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG)); if((r=QueueMess(caller_ptr->p_endpoint, linaddr, dst_ptr)) != OK) return r; RTS_UNSET(dst_ptr, RTS_RECEIVING); @@ -643,7 +615,7 @@ int flags; int i, r, src_id, src_proc_nr, src_p; phys_bytes linaddr; - vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG)); + assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG)); if(!(linaddr = umap_local(caller_ptr, D, (vir_bytes) m_ptr, sizeof(message)))) { @@ -695,8 +667,8 @@ int flags; /* Found a suitable source, deliver the notification message. */ BuildNotifyMessage(&m, src_proc_nr, caller_ptr); /* assemble message */ hisep = proc_addr(src_proc_nr)->p_endpoint; - vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG)); - vmassert(src_e == ANY || hisep == src_e); + assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG)); + assert(src_e == ANY || hisep == src_e); if((r=QueueMess(hisep, vir2phys(&m), caller_ptr)) != OK) { panic("mini_receive: local QueueMess failed"); } @@ -708,18 +680,11 @@ int flags; xpp = &caller_ptr->p_caller_q; while (*xpp != NIL_PROC) { if (src_e == ANY || src_p == proc_nr(*xpp)) { -#if DEBUG_SCHED_CHECK - if (RTS_ISSET(*xpp, RTS_SLOT_FREE) || RTS_ISSET(*xpp, RTS_NO_ENDPOINT)) - { - printf("%d: receive from %d; found dead %d (%s)?\n", - caller_ptr->p_endpoint, src_e, (*xpp)->p_endpoint, - (*xpp)->p_name); - return EINVAL; - } -#endif + assert(!RTS_ISSET(*xpp, RTS_SLOT_FREE)); + assert(!RTS_ISSET(*xpp, RTS_NO_ENDPOINT)); /* Found acceptable message. Copy it and update status. */ - vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG)); + assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG)); QueueMess((*xpp)->p_endpoint, vir2phys(&(*xpp)->p_sendmsg), caller_ptr); if ((*xpp)->p_misc_flags & MF_SIG_DELAY) @@ -791,7 +756,7 @@ endpoint_t dst_e; /* which process to notify */ * message is in the kernel's address space. */ BuildNotifyMessage(&m, proc_nr(caller_ptr), dst_ptr); - vmassert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG)); + assert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG)); if((r=QueueMess(caller_ptr->p_endpoint, vir2phys(&m), dst_ptr)) != OK) { panic("mini_notify: local QueueMess failed"); } @@ -955,7 +920,7 @@ PRIVATE int mini_senda(struct proc *caller_ptr, asynmsg_t *table, size_t size) dst_ptr = proc_addr(dst_p); /* RTS_NO_ENDPOINT should be removed */ - if (dst_ptr->p_rts_flags & RTS_NO_ENDPOINT) + if (RTS_ISSET(dst_ptr, RTS_NO_ENDPOINT)) { tabent.result= EDEADSRCDST; A_INSERT(i, result); @@ -1029,7 +994,7 @@ struct proc *caller_ptr; src_ptr= proc_addr(privp->s_proc_nr); - vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG)); + assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG)); r= try_one(src_ptr, caller_ptr, &postponed); if (r == OK) return r; @@ -1163,14 +1128,12 @@ register struct proc *rp; /* this process is now runnable */ NOREC_ENTER(enqueuefunc); -#if DEBUG_SCHED_CHECK - if (rp->p_ready) panic("enqueue already ready process"); -#endif + assert(proc_is_runnable(rp)); /* Determine where to insert to process. */ sched(rp, &q, &front); - vmassert(q >= 0); + assert(q >= 0); /* Now add the process to the queue. */ if (rdy_head[q] == NIL_PROC) { /* add to empty queue */ @@ -1187,23 +1150,18 @@ register struct proc *rp; /* this process is now runnable */ rp->p_nextready = NIL_PROC; /* mark new end */ } -#if DEBUG_SCHED_CHECK - rp->p_ready = 1; - CHECK_RUNQUEUES; -#endif - /* * enqueueing a process with a higher priority than the current one, it gets * preempted. The current process must be preemptible. Testing the priority * also makes sure that a process does not preempt itself */ - vmassert(proc_ptr); + assert(proc_ptr && proc_ptr_ok(proc_ptr)); if ((proc_ptr->p_priority > rp->p_priority) && (priv(proc_ptr)->s_flags & PREEMPTIBLE)) RTS_SET(proc_ptr, RTS_PREEMPTED); /* calls dequeue() */ -#if DEBUG_SCHED_CHECK - CHECK_RUNQUEUES; +#if DEBUG_SANITYCHECKS + assert(runqueues_ok()); #endif NOREC_RETURN(enqueuefunc, ); @@ -1222,17 +1180,18 @@ PRIVATE void enqueue_head(struct proc *rp) { int q = rp->p_priority; /* scheduling queue to use */ -#if DEBUG_SCHED_CHECK - if (rp->p_ready) panic("enqueue already ready process"); -#endif + assert(proc_ptr_ok(rp)); + assert(proc_is_runnable(rp)); /* * the process was runnable without its quantum expired when dequeued. A * process with no time left should vahe been handled else and differently */ - vmassert(rp->p_ticks_left); +#if 0 + assert(rp->p_ticks_left); +#endif - vmassert(q >= 0); + assert(q >= 0); /* Now add the process to the queue. */ @@ -1244,9 +1203,8 @@ PRIVATE void enqueue_head(struct proc *rp) rp->p_nextready = rdy_head[q]; /* chain head of queue */ rdy_head[q] = rp; /* set new queue head */ -#if DEBUG_SCHED_CHECK - rp->p_ready = 1; - CHECK_RUNQUEUES; +#if DEBUG_SANITYCHECKS + assert(runqueues_ok()); #endif } @@ -1266,17 +1224,11 @@ register struct proc *rp; /* this process is no longer runnable */ NOREC_ENTER(dequeuefunc); -#if DEBUG_STACK_CHECK - /* Side-effect for kernel: check if the task's stack still is ok? */ - if (iskernelp(rp)) { - if (*priv(rp)->s_stack_guard != STACK_GUARD) - panic("stack overrun by task: %d", proc_nr(rp)); - } -#endif + assert(proc_ptr_ok(rp)); + assert(!proc_is_runnable(rp)); -#if DEBUG_SCHED_CHECK - if (! rp->p_ready) panic("dequeue() already unready process"); -#endif + /* Side-effect for kernel: check if the task's stack still is ok? */ + assert (!iskernelp(rp) || *priv(rp)->s_stack_guard == STACK_GUARD); /* 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 @@ -1284,23 +1236,19 @@ register struct proc *rp; /* this process is no longer runnable */ */ prev_xp = NIL_PROC; for (xpp = &rdy_head[q]; *xpp != NIL_PROC; xpp = &(*xpp)->p_nextready) { - if (*xpp == rp) { /* found process to remove */ *xpp = (*xpp)->p_nextready; /* replace with next chain */ - if (rp == rdy_tail[q]) /* queue tail removed */ + if (rp == rdy_tail[q]) { /* queue tail removed */ rdy_tail[q] = prev_xp; /* set new tail */ + } -#if DEBUG_SCHED_CHECK - rp->p_ready = 0; - CHECK_RUNQUEUES; -#endif break; } prev_xp = *xpp; /* save previous in chain */ } -#if DEBUG_SCHED_CHECK - CHECK_RUNQUEUES; +#if DEBUG_SANITYCHECKS + assert(runqueues_ok()); #endif NOREC_RETURN(dequeuefunc, ); @@ -1362,7 +1310,7 @@ PRIVATE struct proc * pick_proc(void) } TRACE(VF_PICKPROC, printf("found %s / %d on queue %d\n", rp->p_name, rp->p_endpoint, q);); - vmassert(!proc_is_runnable(rp)); + assert(proc_is_runnable(rp)); if (priv(rp)->s_flags & BILLABLE) bill_ptr = rp; /* bill for system time */ return rp; @@ -1389,10 +1337,17 @@ timer_t *tp; /* watchdog timer pointer */ for (rp=BEG_PROC_ADDR; rpp_priority > rp->p_max_priority) { /* update priority? */ - if (proc_is_runnable(rp)) dequeue(rp); /* take off queue */ + int paused = 0; + if (proc_is_runnable(rp)) { + RTS_SET(rp, RTS_PROC_STOP); /* take off queue */ + paused = 1; + } ticks_added += rp->p_quantum_size; /* do accounting */ rp->p_priority -= 1; /* raise priority */ - if (proc_is_runnable(rp)) enqueue(rp); /* put on queue */ + if(paused) { + RTS_UNSET(rp, RTS_PROC_STOP); + assert(proc_is_runnable(rp)); + } } else { ticks_added += rp->p_quantum_size - rp->p_ticks_left; diff --git a/kernel/proc.h b/kernel/proc.h index c2f05ea20..8f67988ad 100644 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -98,23 +98,14 @@ struct proc { /* VM result when available */ int vmresult; -#if DEBUG_VMASSERT - char stacktrace[200]; -#endif - /* If the suspended operation is a sys_call, its details are * stored here. */ } p_vmrequest; - struct proc *next_soft_notify; - int p_softnotified; - -#if DEBUG_SCHED_CHECK - int p_ready, p_found; + int p_found; /* consistency checking variables */ #define PMAGIC 0xC0FFEE1 - int p_magic; /* check validity of proc pointers */ -#endif + int p_magic; /* check validity of proc pointers */ #if DEBUG_TRACE int p_schedules; @@ -156,6 +147,7 @@ struct proc { #define proc_is_preempted(p) ((p)->p_rts_flags & RTS_PREEMPTED) #define proc_no_quantum(p) ((p)->p_rts_flags & RTS_NO_QUANTUM) +#define proc_ptr_ok(p) ((p)->p_magic == PMAGIC) /* Macro to return: on which process is a certain process blocked? * return endpoint number (can be ANY) or NONE. It's important to @@ -184,8 +176,11 @@ struct proc { /* Set flag and dequeue if the process was runnable. */ #define RTS_SET(rp, f) \ do { \ - if(proc_is_runnable(rp)) { dequeue(rp); } \ - (rp)->p_rts_flags |= (f); \ + int rts = (rp)->p_rts_flags; \ + (rp)->p_rts_flags |= (f); \ + if(rts_f_is_runnable(rts) && !proc_is_runnable(rp)) { \ + dequeue(rp); \ + } \ } while(0) /* Clear flag and enqueue if the process was not runnable but is now. */ diff --git a/kernel/proto.h b/kernel/proto.h index fdcd6980f..c3261d399 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -88,10 +88,7 @@ _PROTOTYPE( void enable_irq, (irq_hook_t *hook) ); _PROTOTYPE( int disable_irq, (irq_hook_t *hook) ); /* debug.c */ -#if DEBUG_SCHED_CHECK -#define CHECK_RUNQUEUES check_runqueues_f(__FILE__, __LINE__) -_PROTOTYPE( void check_runqueues_f, (char *file, int line) ); -#endif +_PROTOTYPE( int runqueues_ok, (void) ); _PROTOTYPE( char *rtsflagstr, (int flags) ); _PROTOTYPE( char *miscflagstr, (int flags) ); diff --git a/kernel/system.c b/kernel/system.c index 6cc9179b3..82c0c1752 100644 --- a/kernel/system.c +++ b/kernel/system.c @@ -36,6 +36,7 @@ #include "proc.h" #include "vm.h" #include +#include #include #include #include @@ -63,8 +64,8 @@ PRIVATE void kernel_call_finish(struct proc * caller, message *msg, int result) * until VM tells us it's allowed. VM has been notified * and we must wait for its reply to restart the call. */ - vmassert(RTS_ISSET(caller, RTS_VMREQUEST)); - vmassert(caller->p_vmrequest.type == VMSTYPE_KERNELCALL); + assert(RTS_ISSET(caller, RTS_VMREQUEST)); + assert(caller->p_vmrequest.type == VMSTYPE_KERNELCALL); caller->p_vmrequest.saved.reqmsg = *msg; caller->p_misc_flags |= MF_KCALL_RESUME; } else { @@ -536,10 +537,10 @@ PUBLIC void kernel_call_resume(struct proc *caller) { int result; - vmassert(!RTS_ISSET(p, RTS_SLOT_FREE)); - vmassert(!RTS_ISSET(p, RTS_VMREQUEST)); + assert(!RTS_ISSET(caller, RTS_SLOT_FREE)); + assert(!RTS_ISSET(caller, RTS_VMREQUEST)); - vmassert(p->p_vmrequest.saved.reqmsg.m_source == p->p_endpoint); + assert(caller->p_vmrequest.saved.reqmsg.m_source == caller->p_endpoint); /* printf("KERNEL_CALL restart from %s / %d rts 0x%08x misc 0x%08x\n", diff --git a/kernel/system/do_fork.c b/kernel/system/do_fork.c index 294b0f238..0eaccf3b6 100644 --- a/kernel/system/do_fork.c +++ b/kernel/system/do_fork.c @@ -12,6 +12,7 @@ #include "../vm.h" #include #include +#include #include @@ -40,7 +41,7 @@ PUBLIC int do_fork(struct proc * caller, message * m_ptr) rpc = proc_addr(m_ptr->PR_SLOT); if (isemptyp(rpp) || ! isemptyp(rpc)) return(EINVAL); - vmassert(!(rpp->p_misc_flags & MF_DELIVERMSG)); + assert(!(rpp->p_misc_flags & MF_DELIVERMSG)); /* needs to be receiving so we know where the message buffer is */ if(!RTS_ISSET(rpp, RTS_RECEIVING)) { diff --git a/kernel/system/do_safemap.c b/kernel/system/do_safemap.c index 65555949c..f442293bc 100644 --- a/kernel/system/do_safemap.c +++ b/kernel/system/do_safemap.c @@ -11,6 +11,8 @@ * SMAP_FLAG access, writable map or not? */ +#include + #include #include @@ -139,10 +141,10 @@ PUBLIC int map_invoke_vm(struct proc * caller, return EINVAL; } - vmassert(!RTS_ISSET(caller, RTS_VMREQUEST)); - vmassert(!RTS_ISSET(caller, RTS_VMREQTARGET)); - vmassert(!RTS_ISSET(dst, RTS_VMREQUEST)); - vmassert(!RTS_ISSET(dst, RTS_VMREQTARGET)); + assert(!RTS_ISSET(caller, RTS_VMREQUEST)); + assert(!RTS_ISSET(caller, RTS_VMREQTARGET)); + assert(!RTS_ISSET(dst, RTS_VMREQUEST)); + assert(!RTS_ISSET(dst, RTS_VMREQTARGET)); RTS_SET(caller, RTS_VMREQUEST); RTS_SET(dst, RTS_VMREQTARGET); diff --git a/kernel/system/do_vmctl.c b/kernel/system/do_vmctl.c index 94adbde3c..862e586a3 100644 --- a/kernel/system/do_vmctl.c +++ b/kernel/system/do_vmctl.c @@ -10,6 +10,7 @@ #include "../system.h" #include "../vm.h" #include "../debug.h" +#include #include /*===========================================================================* @@ -33,33 +34,17 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr) switch(m_ptr->SVMCTL_PARAM) { case VMCTL_CLEAR_PAGEFAULT: + assert(RTS_ISSET(p,RTS_PAGEFAULT)); RTS_UNSET(p, RTS_PAGEFAULT); return OK; case VMCTL_MEMREQ_GET: /* Send VM the information about the memory request. */ if(!(rp = vmrequest)) return ESRCH; - vmassert(RTS_ISSET(rp, RTS_VMREQUEST)); + assert(RTS_ISSET(rp, RTS_VMREQUEST)); -#if 0 - printf("kernel: vm request sent by: %s / %d about %d; 0x%lx-0x%lx, wr %d, stack: %s ", - rp->p_name, rp->p_endpoint, rp->p_vmrequest.who, - rp->p_vmrequest.start, - rp->p_vmrequest.start + rp->p_vmrequest.length, - rp->p_vmrequest.writeflag, rp->p_vmrequest.stacktrace); - printf("type %d\n", rp->p_vmrequest.type); -#endif - -#if DEBUG_VMASSERT - okendpt(rp->p_vmrequest.who, &proc_nr); + okendpt(rp->p_vmrequest.target, &proc_nr); target = proc_addr(proc_nr); -#if 0 - if(!RTS_ISSET(target, RTS_VMREQTARGET)) { - printf("set stack: %s\n", rp->p_vmrequest.stacktrace); - panic( "RTS_VMREQTARGET not set for target"); - } -#endif -#endif /* Reply with request fields. */ switch(rp->p_vmrequest.req_type) { @@ -75,9 +60,11 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr) m_ptr->SVMCTL_MRG_REQUESTOR = (void *) rp->p_endpoint; break; - case VMPTYPE_COWMAP: case VMPTYPE_SMAP: case VMPTYPE_SUNMAP: + case VMPTYPE_COWMAP: + assert(RTS_ISSET(target,RTS_VMREQTARGET)); + RTS_UNSET(target, RTS_VMREQTARGET); m_ptr->SVMCTL_MRG_TARGET = rp->p_vmrequest.target; m_ptr->SVMCTL_MRG_ADDR = @@ -104,27 +91,12 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr) return rp->p_vmrequest.req_type; case VMCTL_MEMREQ_REPLY: - vmassert(RTS_ISSET(p, RTS_VMREQUEST)); - vmassert(p->p_vmrequest.vmresult == VMSUSPEND); + assert(RTS_ISSET(p, RTS_VMREQUEST)); + assert(p->p_vmrequest.vmresult == VMSUSPEND); okendpt(p->p_vmrequest.target, &proc_nr); target = proc_addr(proc_nr); p->p_vmrequest.vmresult = m_ptr->SVMCTL_VALUE; - vmassert(p->p_vmrequest.vmresult != VMSUSPEND); -#if DEBUG_VMASSERT - if(p->p_vmrequest.vmresult != OK) - printf("SYSTEM: VM replied %d to mem request\n", - p->p_vmrequest.vmresult); - - printf("memreq reply: vm request sent by: %s / %d about %d; 0x%lx-0x%lx, wr %d, stack: %s ", - p->p_name, p->p_endpoint, p->p_vmrequest.who, - p->p_vmrequest.start, - p->p_vmrequest.start + p->p_vmrequest.length, - p->p_vmrequest.writeflag, p->p_vmrequest.stacktrace); - printf("type %d\n", p->p_vmrequest.type); -#endif - - vmassert(RTS_ISSET(target, RTS_VMREQTARGET)); - RTS_UNSET(target, RTS_VMREQTARGET); + assert(p->p_vmrequest.vmresult != VMSUSPEND); switch(p->p_vmrequest.type) { case VMSTYPE_KERNELCALL: @@ -135,19 +107,15 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr) p->p_misc_flags |= MF_KCALL_RESUME; break; case VMSTYPE_DELIVERMSG: - vmassert(p->p_misc_flags & MF_DELIVERMSG); - vmassert(p == target); - vmassert(RTS_ISSET(p, RTS_VMREQUEST)); + assert(p->p_misc_flags & MF_DELIVERMSG); + assert(p == target); + assert(RTS_ISSET(p, RTS_VMREQUEST)); break; case VMSTYPE_MAP: - vmassert(RTS_ISSET(p, RTS_VMREQUEST)); + assert(RTS_ISSET(p, RTS_VMREQUEST)); break; default: -#if DEBUG_VMASSERT - printf("suspended with stack: %s\n", - p->p_vmrequest.stacktrace); -#endif - panic( "strange request type: %d",p->p_vmrequest.type); + panic("strange request type: %d",p->p_vmrequest.type); } RTS_UNSET(p, RTS_VMREQUEST); @@ -159,15 +127,14 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr) vm_init(p); if(!vm_running) panic("do_vmctl: paging enabling failed"); - vmassert(p->p_delivermsg_lin == - umap_local(p, D, p->p_delivermsg_vir, sizeof(message))); if ((err = arch_enable_paging()) != OK) { return err; } if(newmap(caller, p, (struct mem_map *) m_ptr->SVMCTL_VALUE) != OK) panic("do_vmctl: newmap failed"); FIXLINMSG(p); - vmassert(p->p_delivermsg_lin); + assert(p->p_delivermsg_lin == + umap_local(p, D, p->p_delivermsg_vir, sizeof(message))); return OK; case VMCTL_KERN_PHYSMAP: {