kernel: deadlock test with endpoints instead of slot numbers, slightly cleaner
This commit is contained in:
parent
5d47cafa5b
commit
b9cea27497
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user