使用mstar 648开发出现待机失败重启问题,根据分析是因为某个I2c设备未正确读取导致关机时有个线程无法关闭导致无法正常待机
首先待机失败log
os : [TSP_DBG]TSP ISR Proc End!!!
01-01 20:01:36.793 1557 1557 I tvos : player get EV_SIGNAL_UNSTABLE event = 536875042
01-01 20:01:36.793 1557 1557 I tvos : [AutoTest][SourceChange][player finalize END][96823]
01-01 20:01:36.793 1557 1557 I tvos : [ERROR] MSrv_Picture::SetPictureSetting, enInputSrc = 44
01-01 20:01:36.793 1338 1734 E IPlayerImplClient: Send NOTIFY_CALLBACK
01-01 20:01:36.793 1557 1557 I tvos : EV_SIGNAL_UNSTABLE = 536875042
01-01 20:01:36.793 1557 1557 I tvos : Send NOTIFY_CALLBACK
01-01 20:01:36.793 3020 3034 E PlayerImpl_JNI: notifyCB event = 536875042
01-01 20:01:36.793 3020 3034 D PlayerImpl_JNI: Signal status: SIGNAL_UNSTABLE
01-01 20:01:36.825 1557 1557 I tvos : ******Amplifier_RT9113B_SWMute(0)
01-01 20:01:36.826 1557 1557 I tvos : 9113Bwrite fail = 6
01-01 20:01:36.828 1557 1557 I tvos : error: Input type source number is too large!!!
01-01 20:01:36.828 1557 1557 I tvos : [AutoTest][SourceChange][SetInputSourceCmd END][96857]
01-01 20:01:36.828 1557 1557 I tvos : mapi_str::addStrThreadItem ptid=0xd60ff460 m_StrThreadItems.size()=7,this=0xcbf678, name=SSSoundSuspend
01-01 20:01:36.828 1557 1557 I tvos : ******Amplifier_RT9113B_SWMute(1)
01-01 20:01:36.829 1557 1557 I tvos : 9113Bwrite fail = 6
01-01 20:01:36.833 1557 1557 I tvos : mapi_str::removeStrThreadItem ptid=0xd98bf460 m_StrThreadItems.size()=6,this=0xcbf678, name=AudioMonitor
01-01 20:01:36.833 1557 1557 I tvos : [[utopia]] Start HAL_AUDIO_DeAllocateVars g_bInitShmFlag=1
01-01 20:01:36.833 1557 1557 I tvos : [[utopia]] HAL_AUDIO_DeAllocateVars ClientCounter=3
01-01 20:01:36.833 1557 1557 I tvos : [[utopia]] End HAL_AUDIO_DeAllocateVars g_bInitShmFlag=0
01-01 20:01:36.868 1557 1557 I tvos : IRQ 209 polling thread destroyed
01-01 20:01:36.868 1557 1557 I tvos : IRQ 209 polling fd closed!!
01-01 20:01:36.868 1557 1557 I tvos : mapi_str::removeStrThreadItem ptid=0xd3fff460 m_StrThreadItems.size()=5,this=0xcbf678, name=CECMonitor
01-01 20:01:36.868 1557 1557 I tvos : [CEC] MSrv_CEC::Finalize()
01-01 20:01:36.873 1557 1557 I tvos : mapi_str::removeStrThreadItem ptid=0xd40ff460 m_StrThreadItems.size()=4,this=0xcbf678, name=Dont Need Delay
01-01 20:01:36.937 1557 1557 I tvos : IRQ 142 polling thread destroyed
01-01 20:01:36.937 1557 1557 I tvos : IRQ 142 polling fd closed!!
01-01 20:01:36.937 1557 1557 I tvos : mapi_str::removeStrThreadItem ptid=0xd60ff460 m_StrThreadItems.size()=3,this=0xcbf678, name=SSSoundSuspend
01-01 20:01:36.974 1557 1557 I tvos : mapi_str::removeStrThreadItem ptid=0xd41ff460 m_StrThreadItems.size()=2,this=0xcbf678, name=Need Delay SrcD
01-01 20:01:36.984 1557 1557 I tvos : mapi_str::removeStrThreadItem ptid=0xeda38460 m_StrThreadItems.size()=1,this=0xcbf678, name=Picture Monitor
01-01 20:01:36.984 1338 1338 F HDCP2X : [HDCP2X] Enter HDCP2_SuspendHDMI() function ((HDCP2_SuspendHDMI:702))
01-01 20:01:36.984 1338 1338 F HDCP2X : [HDCP2X] Leave HDCP2_SuspendHDMI() function ((HDCP2_SuspendHDMI:708))
01-01 20:01:36.984 1557 1557 I tvos : mapi_str::waitforAllThreadSuspend begin m_StrThreadItems.size()=1,m_StrThreadItemSuspendNum=0,this=0xcbf678,pthread_self()=0xf63c3210,getpid()=1338
01-01 20:01:36.984 1557 1557 I tvos : mapi_str::waitforAllThreadSuspend continue thread ptid=0xe2eac460, name=InitSSoundthrea
01-01 20:01:37.037 1557 1557 I tvos : mapi_str::waitforAllThreadSuspend continue m_StrThreadItems.size()=1,m_StrThreadItemSuspendNum=0,this=0xcbf678,pthread_self()=0xf63c3210,getpid()=1338
01-01 20:01:37.037 1557 1557 I tvos : mapi_str::waitforAllThreadSuspend continue thread ptid=0xe2eac460, name=InitSSoundthrea
01-01 20:01:37.090 1557 1557 I tvos : mapi_str::waitforAllThreadSuspend continue m_StrThreadItems.size()=1,m_StrThreadItemSuspendNum=0,this=0xcbf678,pthread_self()=0xf63c3210,getpid()=1338
01-01 20:01:37.090 1557 1557 I tvos : mapi_str::waitforAllThreadSuspend continue thread ptid=0xe2eac460, name=InitSSoundthrea
01-01 20:01:37.122 1557 1557 I tvos : [INFO] Change to Voltage: 1150 mV (0x30)
从log可以看出执行removeStrThreadItem时AudioMonitor项出现失败问题
removeStrThreadItem方法代码
supernova\MStarSDK\src\str\mapi_str.cpp
void mapi_str::removeStrThreadItem()
{
pthread_t ptid = pthread_self();
char name[32];
int intPTHChk;
prctl(PR_GET_NAME,(unsigned long)name);
intPTHChk = PTH_RET_CHK(pthread_mutex_lock(&m_mutex));
ASSERT(intPTHChk == 0);
for (vector<ST_STR_THREAD_ITEM>::iterator it=m_StrThreadItems.begin(); it!=m_StrThreadItems.end();)
{
if (it->ptid == ptid)
{
it = m_StrThreadItems.erase(it);
printf("mapi_str::removeStrThreadItem ptid=%p m_StrThreadItems.size()=%d,this=%p, name=%s\n", (void*)ptid, m_StrThreadItems.size(), this, name);
}
else
{
++it;
}
}
intPTHChk = PTH_RET_CHK(pthread_mutex_unlock(&m_mutex));
ASSERT(intPTHChk == 0);
}
从代码可以看出当出现问题时m_StrThreadItems数组并未能删除问题线程记录
接着查看mapi_str::waitforAllThreadSuspend 打印log处代码
void mapi_str::waitforAllThreadSuspend()
{
printf("mapi_str::waitforAllThreadSuspend begin m_StrThreadItems.size()=%d,m_StrThreadItemSuspendNum=%u,this=%p,pthread_self()=%p,getpid()=%d\n", m_StrThreadItems.size(), m_StrThreadItemSuspendNum, this, (void*)pthread_self(), getpid());
while(m_StrThreadItems.size() != m_StrThreadItemSuspendNum)
{
for (unsigned int i = 0; i < m_StrThreadItems.size(); i++)
{
printf("mapi_str::waitforAllThreadSuspend continue thread ptid=%p, name=%s\n", (void *)m_StrThreadItems[i].ptid, m_StrThreadItems[i].name.c_str());
}
for(int i=0;i<50;i++)
{
if(m_StrThreadItems.size() == m_StrThreadItemSuspendNum)break;
usleep(1000);
}
printf("mapi_str::waitforAllThreadSuspend continue m_StrThreadItems.size()=%d,m_StrThreadItemSuspendNum=%u,this=%p,pthread_self()=%p,getpid()=%d\n", m_StrThreadItems.size(), m_StrThreadItemSuspendNum, this, (void*)pthread_self(), getpid());
}
printf("mapi_str::waitforAllThreadSuspend complete m_StrThreadItems.size()=%d,m_StrThreadItemSuspendNum=%u,this=%p,pthread_self()=%p,getpid()=%d\n", m_StrThreadItems.size(), m_StrThreadItemSuspendNum, this, (void*)pthread_self(), getpid());
}
查看代码发现,啥都没干只是打印,阻塞时间?难道是在等有其他地方线程去把线程结束删除?分析这边应该就是导致系统待机失败,阻塞时间过长其他地方出现问题直接重启了
这时就有几种修改方法,第一种解决释放不了线程问题,第二种解决这个啥都不干在这阻塞的代码
明显第二种会简单很多添加代码:
void mapi_str::waitforAllThreadSuspend()
{
printf("mapi_str::waitforAllThreadSuspend begin m_StrThreadItems.size()=%d,m_StrThreadItemSuspendNum=%u,this=%p,pthread_self()=%p,getpid()=%d\n", m_StrThreadItems.size(), m_StrThreadItemSuspendNum, this, (void*)pthread_self(), getpid());
while(m_StrThreadItems.size() != m_StrThreadItemSuspendNum)
{
for (unsigned int i = 0; i < m_StrThreadItems.size(); i++)
{
printf("mapi_str::waitforAllThreadSuspend continue thread ptid=%p, name=%s\n", (void *)m_StrThreadItems[i].ptid, m_StrThreadItems[i].name.c_str());
}
for(int i=0;i<50;i++)
{
if(m_StrThreadItems.size() == m_StrThreadItemSuspendNum)break;
usleep(1000);
m_StrThreadItems.clear();
}
printf("mapi_str::waitforAllThreadSuspend continue m_StrThreadItems.size()=%d,m_StrThreadItemSuspendNum=%u,this=%p,pthread_self()=%p,getpid()=%d\n", m_StrThreadItems.size(), m_StrThreadItemSuspendNum, this, (void*)pthread_self(), getpid());
}
printf("mapi_str::waitforAllThreadSuspend complete m_StrThreadItems.size()=%d,m_StrThreadItemSuspendNum=%u,this=%p,pthread_self()=%p,getpid()=%d\n", m_StrThreadItems.size(), m_StrThreadItemSuspendNum, this, (void*)pthread_self(), getpid());
}
重新升级,验证问题成功解决,不过第二种虽然简单但是会不会引起什么问题呢?理论来说待机时候这个没影响,但是最优的解决方法还是第一种