#include "proto.h"
#include <signal.h>
#include <string.h>
+#include <assert.h>
#include "../../proc.h"
#include "../../proto.h"
reg_t pagefaultcr2;
- vmassert(frame);
+ assert(frame);
pagefaultcr2 = read_cr2();
#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) &&
}
/* 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,
#include <minix/syslib.h>
#include <minix/cpufeature.h>
#include <string.h>
+#include <assert.h>
#include <machine/vm.h>
if(vm_running)
panic("vm_init: vm_running");
switch_address_space(newptproc);
+ assert(ptproc == newptproc);
vm_enable_paging();
vm_running = 1;
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 { \
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 { \
#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; \
} \
}
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;
/* 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;
}
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;
/* 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)) {
} 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);
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;
/* 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;
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);
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;
}
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;
{
int pde;
- vmassert(!((u32_t) root % I386_PAGE_SIZE));
+ assert(!((u32_t) root % I386_PAGE_SIZE));
printf("page table 0x%lx:\n", root);
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.
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);
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);
}
}
NOREC_RETURN(virtualcopy, r);
}
- vmassert(procs[_SRC_] && procs[_DST_]);
+ assert(procs[_SRC_] && procs[_DST_]);
if(r == EFAULT_SRC) {
lin = phys_addr[_SRC_];
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))
#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)
#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
#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(;;); \
#include "kernel.h"
#include <string.h>
#include <unistd.h>
+#include <assert.h>
#include <a.out.h>
#include <minix/com.h>
#include <minix/endpoint.h>
*/
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 */
}
* 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
cycles_accounting_init();
DEBUGMAX(("done\n"));
+ assert(runqueues_ok());
+
restart();
NOT_REACHABLE;
}
#include <stddef.h>
#include <signal.h>
#include <minix/syslib.h>
+#include <assert.h>
#include "debug.h"
#include "kernel.h"
* 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)) {
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);
}
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);
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? */
/* 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
*/
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);
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)))) {
/* 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");
}
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)
* 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");
}
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);
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;
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 */
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, );
{
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. */
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
}
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
*/
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, );
}
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;
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;
/* 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;
#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
/* 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. */
_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) );
#include "proc.h"
#include "vm.h"
#include <stdlib.h>
+#include <assert.h>
#include <signal.h>
#include <unistd.h>
#include <sys/sigcontext.h>
* 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 {
{
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",
#include "../vm.h"
#include <signal.h>
#include <string.h>
+#include <assert.h>
#include <minix/endpoint.h>
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)) {
* SMAP_FLAG access, writable map or not?
*/
+#include <assert.h>
+
#include <minix/type.h>
#include <minix/safecopies.h>
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);
#include "../system.h"
#include "../vm.h"
#include "../debug.h"
+#include <assert.h>
#include <minix/type.h>
/*===========================================================================*
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) {
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 =
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:
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);
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:
{