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:
anjiahao 2024-07-15 11:44:57 +08:00 committed by Xiang Xiao
parent 3d69dbe1c8
commit 97425687cf

View file

@ -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));
}
/****************************************************************************