VirtualBox

Changeset 99901 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
May 22, 2023 2:15:10 PM (21 months ago)
Author:
vboxsync
Message:

IPRT: Cleaned up RTThreadGetExecutionTimeMilli and associated testcase.

Location:
trunk/src/VBox/Runtime
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/os2/thread-os2.cpp

    r98103 r99901  
    325325
    326326
    327 RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pKernelTime, uint64_t *pUserTime)
    328 {
     327RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pcMsKernelTime, uint64_t *pcMsUserTime)
     328{
     329    RT_NOREF(pcMsKernelTime, pcMsUserTime);
    329330    return VERR_NOT_IMPLEMENTED;
    330331}
  • trunk/src/VBox/Runtime/r3/posix/thread-posix.cpp

    r98103 r99901  
    732732
    733733/** @todo move this into platform specific files. */
    734 RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pKernelTime, uint64_t *pUserTime)
     734RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pcMsKernelTime, uint64_t *pcMsUserTime)
    735735{
    736736#if defined(RT_OS_SOLARIS)
    737737    struct rusage ts;
    738     int rc = getrusage(RUSAGE_LWP, &ts);
    739     if (rc)
    740         return RTErrConvertFromErrno(rc);
    741 
    742     *pKernelTime = ts.ru_stime.tv_sec * 1000 + ts.ru_stime.tv_usec / 1000;
    743     *pUserTime   = ts.ru_utime.tv_sec * 1000 + ts.ru_utime.tv_usec / 1000;
     738    int const rc = getrusage(RUSAGE_LWP, &ts);
     739    AsserReturn(rc == 0, RTErrConvertFromErrno(rc));
     740
     741    *pcMsKernelTime = ts.ru_stime.tv_sec * 1000 + ts.ru_stime.tv_usec / 1000;
     742    *pcMsUserTime   = ts.ru_utime.tv_sec * 1000 + ts.ru_utime.tv_usec / 1000;
    744743    return VINF_SUCCESS;
    745744
    746745#elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
    747     /* on Linux, getrusage(RUSAGE_THREAD, ...) is available since 2.6.26 */
     746    /* on Linux, getrusage(RUSAGE_THREAD, ...) is available since 2.6.26. maybe it's slower? */
    748747    struct timespec ts;
    749     int rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
    750     if (rc)
    751         return RTErrConvertFromErrno(rc);
    752 
    753     *pKernelTime = 0;
    754     *pUserTime = (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
     748    int const rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
     749    AssertReturn(rc == 0, RTErrConvertFromErrno(rc));
     750
     751    *pcMsKernelTime = 0;
     752    *pcMsUserTime   = (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
    755753    return VINF_SUCCESS;
    756754
     
    761759    AssertReturn(krc == KERN_SUCCESS, RTErrConvertFromDarwinKern(krc));
    762760
    763     *pKernelTime = ThreadInfo.system_time.seconds * 1000 + ThreadInfo.system_time.microseconds / 1000;
    764     *pUserTime   = ThreadInfo.user_time.seconds   * 1000 + ThreadInfo.user_time.microseconds   / 1000;
    765 
     761    *pcMsKernelTime = ThreadInfo.system_time.seconds * 1000 + ThreadInfo.system_time.microseconds / 1000;
     762    *pcMsUserTime   = ThreadInfo.user_time.seconds   * 1000 + ThreadInfo.user_time.microseconds   / 1000;
    766763    return VINF_SUCCESS;
     764
    767765#elif defined(RT_OS_HAIKU)
    768766    thread_info       ThreadInfo;
     
    770768    AssertReturn(status == B_OK, RTErrConvertFromErrno(status));
    771769
    772     *pKernelTime = ThreadInfo.kernel_time / 1000;
    773     *pUserTime   = ThreadInfo.user_time / 1000;
    774 
     770    *pcMsKernelTime = ThreadInfo.kernel_time / 1000;
     771    *pcMsUserTime   = ThreadInfo.user_time / 1000;
    775772    return VINF_SUCCESS;
     773
    776774#else
     775    RT_NOREF(pcMsKernelTime, pcMsUserTime);
    777776    return VERR_NOT_IMPLEMENTED;
    778777#endif
  • trunk/src/VBox/Runtime/r3/win/thread-win.cpp

    r98103 r99901  
    529529
    530530
    531 RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pKernelTime, uint64_t *pUserTime)
     531RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pcMsKernelTime, uint64_t *pcMsUserTime)
    532532{
    533533    uint64_t u64CreationTime, u64ExitTime, u64KernelTime, u64UserTime;
     
    535535    if (GetThreadTimes(GetCurrentThread(), (LPFILETIME)&u64CreationTime, (LPFILETIME)&u64ExitTime, (LPFILETIME)&u64KernelTime, (LPFILETIME)&u64UserTime))
    536536    {
    537         *pKernelTime = u64KernelTime / 10000;    /* GetThreadTimes returns time in 100 ns units */
    538         *pUserTime   = u64UserTime / 10000;    /* GetThreadTimes returns time in 100 ns units */
     537        *pcMsKernelTime = u64KernelTime / 10000;    /* GetThreadTimes returns time in 100 ns units */
     538        *pcMsUserTime   = u64UserTime / 10000;    /* GetThreadTimes returns time in 100 ns units */
    539539        return VINF_SUCCESS;
    540540    }
    541541
    542     int iLastError = GetLastError();
    543     AssertMsgFailed(("GetThreadTimes failed, LastError=%d\n", iLastError));
    544     return RTErrConvertFromWin32(iLastError);
     542    DWORD const dwErr = GetLastError();
     543    AssertMsgFailed(("GetThreadTimes failed, LastError=%d\n", dwErr));
     544    return RTErrConvertFromWin32(dwErr);
    545545}
    546546
  • trunk/src/VBox/Runtime/testcase/tstRTThreadExecutionTime.cpp

    r98103 r99901  
    5252*********************************************************************************************************************************/
    5353static RTTEST g_hTest;
    54 static volatile uint64_t g_kernel, g_user;
     54static volatile uint64_t g_cMsKernel;
     55static volatile uint64_t g_cMsUser;
    5556
    5657
    5758static DECLCALLBACK(int) testThread(RTTHREAD hSelf, void *pvUser)
    5859{
    59     RT_NOREF_PV(hSelf); RT_NOREF_PV(pvUser);
     60    RTMSINTERVAL const msWait = *(RTMSINTERVAL const *)pvUser;
     61    RT_NOREF_PV(hSelf);
    6062
    61     uint64_t u64Now = RTTimeMilliTS();
    62     uint64_t kernel, kernelStart, user, userStart;
    63     RTThreadGetExecutionTimeMilli(&kernelStart, &userStart);
    64     while (RTTimeMilliTS() < u64Now + 1000)
    65         ;
    66     RTThreadGetExecutionTimeMilli(&kernel, &user);
    67     RTPrintf("kernel = %4lldms, user = %4lldms\n", kernel - kernelStart, user - userStart);
    68     ASMAtomicAddU64(&g_kernel, kernel);
    69     ASMAtomicAddU64(&g_user, user);
     63    uint64_t const msNow = RTTimeMilliTS();
     64    uint64_t cMsKernelStart, cMsUserStart;
     65    RTTEST_CHECK_RC_RET(g_hTest, RTThreadGetExecutionTimeMilli(&cMsKernelStart, &cMsUserStart), VINF_SUCCESS, rcCheck);
     66
     67    while (RTTimeMilliTS() < msNow + msWait)
     68        ASMNopPause();
     69
     70    uint64_t cMsKernel, cMsUser;
     71    RTTEST_CHECK_RC_RET(g_hTest, RTThreadGetExecutionTimeMilli(&cMsKernel, &cMsUser), VINF_SUCCESS, rcCheck);
     72
     73    cMsKernel -= cMsKernelStart;
     74    cMsUser   -= cMsUserStart;
     75    RTPrintf("kernel = %4lldms, user = %4lldms\n", cMsKernel, cMsUser);
     76    ASMAtomicAddU64(&g_cMsKernel, cMsKernel);
     77    ASMAtomicAddU64(&g_cMsUser,   cMsUser);
    7078
    7179    return VINF_SUCCESS;
     
    7381
    7482
    75 static void test1(void)
     83static void test1(RTMSINTERVAL msWait)
    7684{
    77     RTTestSub(g_hTest, "Interrupt RTThreadSleep");
    78     RTTHREAD hThread[16];
    79     RTMSINTERVAL msWait = 1000;
    80     for (unsigned i = 0; i < RT_ELEMENTS(hThread); i++)
     85    RTTHREAD ahThreads[16];
     86    RTTestSubF(g_hTest, "RTThreadGetExecutionTimeMilli - %zu thread for %u ms", RT_ELEMENTS(ahThreads), (unsigned)msWait);
     87    for (unsigned i = 0; i < RT_ELEMENTS(ahThreads); i++)
     88        RTTESTI_CHECK_RC_RETV(RTThreadCreate(&ahThreads[i], testThread, &msWait, 0, RTTHREADTYPE_DEFAULT,
     89                              RTTHREADFLAGS_WAITABLE, "test"), VINF_SUCCESS);
     90
     91    RTPrintf("Waiting for the threads to complete...\n");
     92    for (unsigned i = 0; i < RT_ELEMENTS(ahThreads); i++)
     93        RTTESTI_CHECK_RC(RTThreadWait(ahThreads[i], msWait * 5, NULL), VINF_SUCCESS);
     94
     95    RTPrintf("sum kernel = %lldms, sum user = %lldms\n", g_cMsKernel, g_cMsUser);
     96}
     97
     98
     99static void test2(void)
     100{
     101    RTTestSub(g_hTest, "RTThreadGetExecutionTimeMilli perf");
     102
     103    /* Run it for ~3 seconds. */
     104    RTThreadYield();
     105    uint64_t       cCalls  = 0;
     106    uint64_t const nsStart = RTTimeNanoTS();
     107    for (;;)
    81108    {
    82         RTTESTI_CHECK_RC_RETV(RTThreadCreate(&hThread[i], testThread, NULL, 0, RTTHREADTYPE_DEFAULT,
    83                               RTTHREADFLAGS_WAITABLE, "test"), VINF_SUCCESS);
     109        uint32_t cLeftBeforeCheck = 16384;
     110        while (cLeftBeforeCheck-- > 0)
     111        {
     112            uint64_t uIgn;
     113            RTThreadGetExecutionTimeMilli(&uIgn, &uIgn);
     114            cCalls++;
     115        }
     116        uint64_t const cNsElapsed = RTTimeNanoTS() - nsStart;
     117        if (cNsElapsed >= RT_NS_1SEC_64 * 3)
     118        {
     119            RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "%'RU64 calls in %'RU64 ns\n", cCalls, cNsElapsed);
     120            RTTestValue(g_hTest, "RTThreadGetExecutionTimeMilli avg.", cNsElapsed * 1000 / cCalls, RTTESTUNIT_PS_PER_CALL);
     121            return;
     122        }
    84123    }
    85     RTThreadSleep(500);
    86     RTPrintf("Waiting for %dms ...\n", msWait);
    87     RTThreadSleep(msWait);
    88     for (unsigned i = 0; i < RT_ELEMENTS(hThread); i++)
    89         RTTESTI_CHECK_RC(RTThreadWait(hThread[i], RT_INDEFINITE_WAIT, NULL), VINF_SUCCESS);
    90 
    91     RTPrintf("sum kernel = %lldms, sum user = %lldms\n", g_kernel, g_user);
    92124}
    93125
     
    98130    if (rcExit != RTEXITCODE_SUCCESS)
    99131        return rcExit;
    100     test1();
     132
     133    uint64_t uIgn;
     134    int rc = RTThreadGetExecutionTimeMilli(&uIgn, &uIgn);
     135    if (rc == VERR_NOT_IMPLEMENTED)
     136        return RTTestSkipAndDestroy(g_hTest, "VERR_NOT_IMPLEMENTED");
     137
     138    test1(RT_MS_1SEC);
     139    test2();
    101140
    102141    return RTTestSummaryAndDestroy(g_hTest);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette