re-establish kernel assert()s.

use the regular <assert.h> assert() instead of vmassert() in
kernel. throw out some #if 0 code. fix a few assert() conditions.
enable by default.
This commit is contained in:
Ben Gras 2010-03-10 13:00:05 +00:00
parent 88ac328e6b
commit 0937d6c367
12 changed files with 192 additions and 305 deletions

View file

@ -7,6 +7,7 @@
#include "proto.h"
#include <signal.h>
#include <string.h>
#include <assert.h>
#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,

View file

@ -8,6 +8,7 @@
#include <minix/syslib.h>
#include <minix/cpufeature.h>
#include <string.h>
#include <assert.h>
#include <machine/vm.h>
@ -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);
assert(rp->p_misc_flags & MF_DELIVERMSG);
assert(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");
}
#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))

View file

@ -11,97 +11,101 @@
#include <limits.h>
#include <string.h>
#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)

View file

@ -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(;;); \

View file

@ -11,6 +11,7 @@
#include "kernel.h"
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <a.out.h>
#include <minix/com.h>
#include <minix/endpoint.h>
@ -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;
}

View file

@ -34,6 +34,7 @@
#include <stddef.h>
#include <signal.h>
#include <minix/syslib.h>
#include <assert.h>
#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; rp<END_PROC_ADDR; rp++) {
if (! isemptyp(rp)) { /* check slot use */
if (rp->p_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;

View file

@ -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. */

View file

@ -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) );

View file

@ -36,6 +36,7 @@
#include "proc.h"
#include "vm.h"
#include <stdlib.h>
#include <assert.h>
#include <signal.h>
#include <unistd.h>
#include <sys/sigcontext.h>
@ -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",

View file

@ -12,6 +12,7 @@
#include "../vm.h"
#include <signal.h>
#include <string.h>
#include <assert.h>
#include <minix/endpoint.h>
@ -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)) {

View file

@ -11,6 +11,8 @@
* SMAP_FLAG access, writable map or not?
*/
#include <assert.h>
#include <minix/type.h>
#include <minix/safecopies.h>
@ -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);

View file

@ -10,6 +10,7 @@
#include "../system.h"
#include "../vm.h"
#include "../debug.h"
#include <assert.h>
#include <minix/type.h>
/*===========================================================================*
@ -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:
{