Modifying the system time to solve the pthread_cond_timedwait timeout problem

Recently, I was investigating a problem that the camera was inexplicably reported that the application for preview timed out during the use of a camera
. The errors reported are as follows:

camxsession.cpp:1269 ProcessCaptureRequest() Lets do a Reset 
camxchi.cpp:588 ChiSubmitPipelineRequest() Submit request failed with error 9.

I thought that the CPU usage was too high, which caused the preview report to time out, and then various analysis performance power consumption. Entered a bigger pit, unable to extricate itself! ! !
Recently, I found the recurrence law. As long as the system time is modified, the above error will be reported! ! ! Sinkeng! ! !

So I carefully studied the code of camx, and inadvertently opened the source code of the lock and found the reason for the sinkhole (oh my god, who would have thought that there was a problem with the implementation of the lock!!) The
code is as follows:

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 took a look and said that the time obtained after changing CLOCK_REALTIME to CLOCK_MONOTONIC can not be affected by the system time.
After the modification, it was found that it still did not take effect. It was originally an occasional problem and became a must! ! ! !

Today, in the universal CSDN, I read a Daniel article:
pthread_cond_timedwait waits for the timeout complete sample code according to the relative time

According to the realization of the article, the problem is solved perfectly

@@ -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);

Guess you like

Origin blog.csdn.net/u010116586/article/details/94748075