kernel: deadlock test with endpoints instead of slot numbers, slightly cleaner

This commit is contained in:
Ben Gras 2010-07-28 14:14:06 +00:00
parent 5d47cafa5b
commit b9cea27497

View File

@ -55,7 +55,7 @@ FORWARD _PROTOTYPE( int mini_receive, (struct proc *caller_ptr, endpoint_t src,
FORWARD _PROTOTYPE( int mini_senda, (struct proc *caller_ptr, FORWARD _PROTOTYPE( int mini_senda, (struct proc *caller_ptr,
asynmsg_t *table, size_t size)); asynmsg_t *table, size_t size));
FORWARD _PROTOTYPE( int deadlock, (int function, FORWARD _PROTOTYPE( int deadlock, (int function,
register struct proc *caller, proc_nr_t src_dst)); register struct proc *caller, endpoint_t src_dst_e));
FORWARD _PROTOTYPE( int try_async, (struct proc *caller_ptr)); FORWARD _PROTOTYPE( int try_async, (struct proc *caller_ptr));
FORWARD _PROTOTYPE( int try_one, (struct proc *src_ptr, struct proc *dst_ptr, FORWARD _PROTOTYPE( int try_one, (struct proc *src_ptr, struct proc *dst_ptr,
int *postponed)); int *postponed));
@ -453,10 +453,10 @@ PUBLIC int do_ipc(reg_t r1, reg_t r2, reg_t r3)
/*===========================================================================* /*===========================================================================*
* deadlock * * deadlock *
*===========================================================================*/ *===========================================================================*/
PRIVATE int deadlock(function, cp, src_dst) PRIVATE int deadlock(function, cp, src_dst_e)
int function; /* trap number */ int function; /* trap number */
register struct proc *cp; /* pointer to caller */ register struct proc *cp; /* pointer to caller */
proc_nr_t src_dst; /* src or dst process */ endpoint_t src_dst_e; /* src or dst process */
{ {
/* Check for deadlock. This can happen if 'caller_ptr' and 'src_dst' have /* Check for deadlock. This can happen if 'caller_ptr' and 'src_dst' have
* a cyclic dependency of blocking send and receive calls. The only cyclic * a cyclic dependency of blocking send and receive calls. The only cyclic
@ -471,10 +471,12 @@ proc_nr_t src_dst; /* src or dst process */
processes[0] = cp; processes[0] = cp;
#endif #endif
/* FIXME: this compares a proc_nr_t with a endpoint_t */ while (src_dst_e != ANY) { /* check while process nr */
while (src_dst != ANY) { /* check while process nr */ int src_dst_slot;
endpoint_t dep; okendpt(src_dst_e, &src_dst_slot);
xp = proc_addr(src_dst); /* follow chain of processes */ xp = proc_addr(src_dst_slot); /* follow chain of processes */
assert(proc_ptr_ok(xp));
assert(!RTS_ISSET(xp, RTS_SLOT_FREE));
#if DEBUG_ENABLE_IPC_WARNINGS #if DEBUG_ENABLE_IPC_WARNINGS
processes[group_size] = xp; processes[group_size] = xp;
#endif #endif
@ -483,20 +485,14 @@ proc_nr_t src_dst; /* src or dst process */
/* Check whether the last process in the chain has a dependency. If it /* Check whether the last process in the chain has a dependency. If it
* has not, the cycle cannot be closed and we are done. * has not, the cycle cannot be closed and we are done.
*/ */
if((dep = P_BLOCKEDON(xp)) == NONE) if((src_dst_e = P_BLOCKEDON(xp)) == NONE)
return 0; return 0;
if(dep == ANY)
/* FIXME: this assigns a proc_nr_t to a endpoint_t */
src_dst = ANY;
else
okendpt(dep, &src_dst);
/* Now check if there is a cyclic dependency. For group sizes of two, /* Now check if there is a cyclic dependency. For group sizes of two,
* a combination of SEND(REC) and RECEIVE is not fatal. Larger groups * a combination of SEND(REC) and RECEIVE is not fatal. Larger groups
* or other combinations indicate a deadlock. * or other combinations indicate a deadlock.
*/ */
if (src_dst == proc_nr(cp)) { /* possible deadlock */ if (src_dst_e == cp->p_endpoint) { /* possible deadlock */
if (group_size == 2) { /* caller and src_dst */ if (group_size == 2) { /* caller and src_dst */
/* The function number is magically converted to flags. */ /* The function number is magically converted to flags. */
if ((xp->p_rts_flags ^ (function << 2)) & RTS_SENDING) { if ((xp->p_rts_flags ^ (function << 2)) & RTS_SENDING) {
@ -586,7 +582,7 @@ PUBLIC int mini_send(
} }
/* Check for a possible deadlock before actually blocking. */ /* Check for a possible deadlock before actually blocking. */
if (deadlock(SEND, caller_ptr, dst_p)) { if (deadlock(SEND, caller_ptr, dst_e)) {
return(ELOCKED); return(ELOCKED);
} }
@ -759,7 +755,7 @@ PRIVATE int mini_receive(struct proc * caller_ptr,
*/ */
if ( ! (flags & NON_BLOCKING)) { if ( ! (flags & NON_BLOCKING)) {
/* Check for a possible deadlock before actually blocking. */ /* Check for a possible deadlock before actually blocking. */
if (deadlock(RECEIVE, caller_ptr, src_p)) { if (deadlock(RECEIVE, caller_ptr, src_e)) {
return(ELOCKED); return(ELOCKED);
} }