mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 09:49:21 +08:00
deadlock:fix find deadlock bug
bug: thread 1: get mutexA wait a sem thread 2: wait mutexA This situation will be mistakenly judged as a deadlock. Signed-off-by: anjiahao <anjiahao@xiaomi.com> Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
This commit is contained in:
parent
3d69dbe1c8
commit
97425687cf
1 changed files with 71 additions and 41 deletions
|
@ -42,58 +42,88 @@ struct deadlock_info_s
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: waitmutex
|
||||
****************************************************************************/
|
||||
|
||||
static FAR mutex_t *getmutex(FAR struct tcb_s *tcb)
|
||||
{
|
||||
FAR sem_t *sem;
|
||||
|
||||
if (tcb == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tcb->task_state == TSTATE_WAIT_SEM)
|
||||
{
|
||||
sem = tcb->waitobj;
|
||||
if (sem != NULL && (sem->flags & SEM_TYPE_MUTEX) != 0)
|
||||
{
|
||||
return (FAR mutex_t *)sem;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: collect_deadlock
|
||||
****************************************************************************/
|
||||
|
||||
static void collect_deadlock(FAR struct tcb_s *tcb, FAR void *arg)
|
||||
{
|
||||
if (tcb->task_state == TSTATE_WAIT_SEM)
|
||||
FAR struct deadlock_info_s *info = arg;
|
||||
FAR mutex_t *mutex;
|
||||
size_t index;
|
||||
|
||||
mutex = getmutex(tcb);
|
||||
if (mutex == NULL)
|
||||
{
|
||||
FAR sem_t *sem = tcb->waitobj;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sem != NULL && (sem->flags & SEM_TYPE_MUTEX) != 0)
|
||||
for (index = 0; index < info->found; index++)
|
||||
{
|
||||
if (info->pid[index] == tcb->pid)
|
||||
{
|
||||
FAR struct deadlock_info_s *info = arg;
|
||||
size_t index;
|
||||
|
||||
for (index = 0; index < info->found; index++)
|
||||
{
|
||||
if (info->pid[index] == tcb->pid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (index = info->found; index < info->count; index++)
|
||||
{
|
||||
pid_t next;
|
||||
size_t i;
|
||||
|
||||
next = ((FAR mutex_t *)sem)->holder;
|
||||
if (next == NXMUTEX_NO_HOLDER)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = info->found; i < index; i++)
|
||||
{
|
||||
if (info->pid[i] == next)
|
||||
{
|
||||
info->found = index;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info->pid[index] = tcb->pid;
|
||||
tcb = nxsched_get_tcb(next);
|
||||
if (tcb == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (index = info->found; index < info->count; index++)
|
||||
{
|
||||
pid_t next;
|
||||
size_t i;
|
||||
|
||||
next = mutex->holder;
|
||||
if (next == NXMUTEX_NO_HOLDER)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = info->found; i < index; i++)
|
||||
{
|
||||
if (info->pid[i] == next)
|
||||
{
|
||||
info->found = index;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info->pid[index] = tcb->pid;
|
||||
tcb = nxsched_get_tcb(next);
|
||||
mutex = getmutex(tcb);
|
||||
if (mutex == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we not find deadlock, clear the pid array */
|
||||
|
||||
memset(&info->pid[info->found], 0,
|
||||
(info->count - info->found) * sizeof(pid_t));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
Loading…
Reference in a new issue