From ad98a3eed0b1128db49d84f19ec5fd18d4b8799e Mon Sep 17 00:00:00 2001 From: "henrike@webrtc.org" Date: Fri, 18 Nov 2011 23:55:12 +0000 Subject: [PATCH] Fixes TEST crash triggered by webrtc-codereview.appspot.com/268014. Review URL: http://webrtc-codereview.appspot.com/280005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@980 4adac7df-926f-26a2-2b94-8c16560cd09d --- src/system_wrappers/interface/cpu_wrapper.h | 6 +++ src/system_wrappers/source/cpu_windows.cc | 12 +++++- .../source/cpu_wrapper_unittest.cc | 40 ++++++++++++++----- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/system_wrappers/interface/cpu_wrapper.h b/src/system_wrappers/interface/cpu_wrapper.h index bcc6a81b5e..368afeb76c 100644 --- a/src/system_wrappers/interface/cpu_wrapper.h +++ b/src/system_wrappers/interface/cpu_wrapper.h @@ -32,6 +32,12 @@ public: // Note that the pointer passed as cpu_usage is redirected to a local member // of the CPU wrapper. // numCores is the number of cores in the cpu_usage array. + // Note: on some OSs this class is initialized lazy. This means that it + // might not yet be possible to retrieve any CPU metrics. When this happens + // the return value will be zero (indicating that there is not a failure), + // numCores will be 0 and cpu_usage will be set to NULL (indicating that + // no metrics are available yet). Once the initialization is completed, + // which can take in the order of seconds, CPU metrics can be retrieved. virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores, WebRtc_UWord32*& cpu_usage) = 0; diff --git a/src/system_wrappers/source/cpu_windows.cc b/src/system_wrappers/source/cpu_windows.cc index ccef55a2dd..c8ff36a885 100644 --- a/src/system_wrappers/source/cpu_windows.cc +++ b/src/system_wrappers/source/cpu_windows.cc @@ -35,11 +35,18 @@ WebRtc_Word32 CpuWindows::CpuUsage() } WebRtc_Word32 CpuWindows::CpuUsageMultiCore(WebRtc_UWord32& num_cores, - WebRtc_UWord32*& cpu_usage) + WebRtc_UWord32*& cpu_usage) { + if (has_terminated_) { + num_cores = 0; + cpu_usage = NULL; + return -1; + } if (!has_initialized_) { - return -1; + num_cores = 0; + cpu_usage = NULL; + return 0; } num_cores = number_of_objects_ - 1; cpu_usage = cpu_usage_; @@ -140,6 +147,7 @@ void CpuWindows::StartPollingCpu() if (!cpu_polling_thread->Start(dummy_id)) { initialize_ = false; + has_terminated_ = true; assert(false); } } diff --git a/src/system_wrappers/source/cpu_wrapper_unittest.cc b/src/system_wrappers/source/cpu_wrapper_unittest.cc index e2e8fb0a70..15a3e74e7a 100644 --- a/src/system_wrappers/source/cpu_wrapper_unittest.cc +++ b/src/system_wrappers/source/cpu_wrapper_unittest.cc @@ -12,6 +12,7 @@ #include "gtest/gtest.h" #include "system_wrappers/interface/cpu_info.h" +#include "system_wrappers/interface/event_wrapper.h" #include "system_wrappers/interface/trace.h" using webrtc::CpuInfo; @@ -28,18 +29,39 @@ TEST(CpuWrapperTest, Usage) { Trace::SetLevelFilter(webrtc::kTraceAll); printf("Number of cores detected:%u\n", CpuInfo::DetectNumberOfCores()); CpuWrapper* cpu = CpuWrapper::CreateCpu(); - WebRtc_UWord32 numCores; - WebRtc_UWord32* cores; - for (int i = 0; i < 10; i++) { - WebRtc_Word32 total = cpu->CpuUsageMultiCore(numCores, cores); + ASSERT_TRUE(cpu != NULL); + webrtc::EventWrapper* sleep_event = webrtc::EventWrapper::Create(); + ASSERT_TRUE(sleep_event != NULL); - printf("\nNumCores:%d\n", numCores); - printf("Total cpu:%d\n", total); - - for (WebRtc_UWord32 i = 0; i < numCores; i++) { - printf("Core:%u CPU:%u \n", i, cores[i]); + int num_iterations = 0; + WebRtc_UWord32 num_cores = 0; + WebRtc_UWord32* cores = NULL; + bool cpu_usage_available = cpu->CpuUsageMultiCore(num_cores, cores) != -1; + // Initializing the CPU measurements may take a couple of seconds on Windows. + // Since the initialization is lazy we need to wait until it is completed. + // Should not take more than 10000 ms. + while (cpu_usage_available && (++num_iterations < 10000)) { + if (cores != NULL) { + ASSERT_GT(num_cores, 0); + break; } + sleep_event->Wait(1); + cpu_usage_available = cpu->CpuUsageMultiCore(num_cores, cores) != -1; } + ASSERT_TRUE(cpu_usage_available); + + const WebRtc_Word32 total = cpu->CpuUsageMultiCore(num_cores, cores); + ASSERT_TRUE(cores != NULL); + EXPECT_GT(num_cores, 0); + EXPECT_GE(total, 0); + + printf("\nNumCores:%d\n", num_cores); + printf("Total cpu:%d\n", total); + for (WebRtc_UWord32 i = 0; i < num_cores; i++) { + printf("Core:%u CPU:%u \n", i, cores[i]); + EXPECT_LE(cores[i], total); + } + delete cpu; Trace::ReturnTrace(); };