最近、カメラの使用中にプレビューのアプリケーションがタイムアウトしたという不可解な報告があったという問題を調査していたところ、
次のエラーが報告されました。
camxsession.cpp:1269 ProcessCaptureRequest() Lets do a Reset
camxchi.cpp:588 ChiSubmitPipelineRequest() Submit request failed with error 9.
CPU使用率が高すぎるため、プレビューレポートがタイムアウトし、さまざまな分析パフォーマンスの電力消費が発生したと思いました。より大きな穴に入り、それ自体を逃れることができませんでした!!!
最近、再発法を発見しましたが、システム時刻が変更されていれば、上記のエラーが報告されます!!!シンケン!!!
だから私はcamxのコードを注意深く研究し、誤ってロックのソースコードを開いて、陥没穴の理由を見つけました(ロックの実装に問題があったと思っていた私の神!!)
コードは次のとおりです:
CamxResult Condition::TimedWait(
OSMutexHandle* phMutex,
UINT timeoutMilliseconds)
{
CamxResult result = CamxResultSuccess;
INT waitResult = 0;
UINT timeoutSeconds = (timeoutMilliseconds / 1000UL);
UINT timeoutNanoseconds = (timeoutMilliseconds % 1000UL) * 1000000UL;
struct timespec timeout = {
0};
// Calculate the timeout time
//通过CLOCK_REALTIME获取的时间是受系统时间影响的!!!
clock_gettime(CLOCK_REALTIME, &timeout);
timeoutSeconds += (static_cast<UINT>(timeout.tv_nsec) + timeoutNanoseconds) / 1000000000UL;
timeoutNanoseconds = (static_cast<UINT>(timeout.tv_nsec) + timeoutNanoseconds) % 1000000000UL;
timeout.tv_sec += static_cast<INT>(timeoutSeconds);
timeout.tv_nsec = static_cast<INT>(timeoutNanoseconds);
//如果在pthread_cond_timedwait的过程中,系统时间突然变大,这个锁直接返回CamxResultETimeout
waitResult = pthread_cond_timedwait(&m_conditionVar, phMutex, &timeout);
if (waitResult != 0)
{
// Check errno for reason for failure
if (ETIMEDOUT == waitResult)
{
result = CamxResultETimeout;
}
else
{
result = CamxResultEFailed;
}
}
return result;
}
Baiduは、CLOCK_REALTIMEをCLOCK_MONOTONICに変更した後に取得された時間はシステム時間の影響を受けないと述べました。
変更後、まだ効果が無いことが判明しましたが、もともとは偶然の問題で必須になりました!!!!
今日、ユニバーサルCSDNで、Danielの記事を読みました。pthread_cond_timedwaitは
、相対時間に従ってタイムアウトの完全なサンプルコードを待機します
記事の実現によると、問題は完全に解決されています
@@ -1741,7 +1741,9 @@ CamxResult Condition::Initialize(
m_pResource = pResource;
- if (pthread_cond_init(&m_conditionVar, NULL) == 0)
+ pthread_condattr_setclock(&m_cattr, CLOCK_MONOTONIC);
+
+ if (pthread_cond_init(&m_conditionVar, &m_cattr) == 0)
{
m_validConditionVar = TRUE;
}
@@ -1795,7 +1797,7 @@ CamxResult Condition::TimedWait(
struct timespec timeout = {
0};
// Calculate the timeout time
- clock_gettime(CLOCK_REALTIME, &timeout);
+ clock_gettime(CLOCK_MONOTONIC, &timeout);