TEST(BasicThreadTest, Stop) { MockThread m; m.start(nullptr); boost::this_thread::sleep(boost::posix_time::milliseconds(100)); EXPECT_TRUE(m.isRunning()); m.stop(); EXPECT_TRUE(m.didBeforeStop); EXPECT_FALSE(m.isRunning()); }
TEST(BasicThreadTest, StopWithoutSleep) { for (int i = 0; i < 10; ++i) { MockThread m; m.count = 1000000; m.start(nullptr); // Stopping right away should not create a race condition. m.stop(); EXPECT_TRUE(m.didBeforeStop); EXPECT_FALSE(m.isRunning()); } }
/* * Check that basic thread functionality works. */ void ThreadTest::testThread() { MockThread thread; OLA_ASSERT_FALSE(thread.HasRan()); OLA_ASSERT_TRUE(thread.Start()); // starting twice must fail OLA_ASSERT_FALSE(thread.Start()); OLA_ASSERT_TRUE(thread.IsRunning()); OLA_ASSERT_TRUE(thread.Join()); OLA_ASSERT_FALSE(thread.IsRunning()); OLA_ASSERT_TRUE(thread.HasRan()); }
TEST(BasicThreadTest, RunTimeManagement) { MockThread m; EXPECT_EQ(-1, m.count); std::shared_ptr<Barrier> barrier = std::make_shared<Barrier>(2); EXPECT_FALSE(m.didInitialize); EXPECT_FALSE(m.didStartUp); EXPECT_FALSE(m.isRunning()); m.start(barrier); boost::this_thread::sleep(boost::posix_time::milliseconds(100)); EXPECT_TRUE(m.isRunning()); EXPECT_TRUE(m.didInitialize); EXPECT_FALSE(m.didStartUp); barrier->wait(true); boost::this_thread::sleep(boost::posix_time::milliseconds(100)); EXPECT_TRUE(m.didInitialize); EXPECT_TRUE(m.didStartUp); barrier->wait(true); boost::this_thread::sleep(boost::posix_time::milliseconds(100)); m.stop(); }
TEST(BasicThreadTest, RealTimings) { MockThread m; m.start(nullptr); while (m.getCpuTime() < 1e-6); EXPECT_GT(m.getCpuTime(), 1e-6); EXPECT_GT(m.getUpdateCount(), 0u); // Ask the manager to idle for a while, just the time for us to reset the timer and check right after // what the timer contains (the delay between the reset and the checks could trigger a race condition). // Asking the thread to idle suppress this race condition. m.setIdle(true); // Reset the timer (=> no more frames in the timer queue) m.resetCpuTimeAndUpdateCount(); EXPECT_NEAR(0.0, m.getCpuTime(), 1e-9); EXPECT_EQ(m.getUpdateCount(), 0u); // Resume the thread loop update. m.setIdle(false); while (m.getCpuTime() < 1e-6); EXPECT_GT(m.getCpuTime(), 1e-6); EXPECT_GT(m.getUpdateCount(), 0u); m.stop(); }
/* * Check that the scheduling options behave as expected. */ void ThreadTest::testSchedulingOptions() { #ifndef _WIN32 #if HAVE_DECL_RLIMIT_RTPRIO struct rlimit rlim; OLA_ASSERT_TRUE(ola::system::GetRLimit(RLIMIT_RTPRIO, &rlim)); if (rlim.rlim_cur == 0) { // A value of 0 means the user can't change policies. OLA_INFO << "Skipping testSchedulingOptions since RLIMIT_RTPRIO is 0"; return; } const int max_priority = rlim.rlim_cur - 1; const int other_priority = std::min(1, max_priority - 1); #else const int max_priority = 31; const int other_priority = 15; #endif // HAVE_DECL_RLIMIT_RTPRIO SchedulingParams default_params = GetCurrentParams(); { // Default scheduling options. MockThread thread; OLA_ASSERT_TRUE(RunThread(&thread)); OLA_ASSERT_EQ(default_params.policy, thread.GetSchedulingParams().policy); OLA_ASSERT_EQ(default_params.priority, thread.GetSchedulingParams().priority); } { // A thread that explicitly sets scheduling params. Thread::Options options; options.name = "ExplicitSchedParamsFIFO"; options.policy = SCHED_FIFO; options.priority = max_priority; MockThread thread(options); OLA_ASSERT_TRUE(RunThread(&thread)); OLA_ASSERT_EQ(static_cast<int>(SCHED_FIFO), thread.GetSchedulingParams().policy); OLA_ASSERT_EQ(max_priority, thread.GetSchedulingParams().priority); } // Set the current thread to something other than the default. // This allows us to check inheritance. SchedulingParams override_params; override_params.policy = SCHED_FIFO; override_params.priority = other_priority; OLA_ASSERT_TRUE(SetCurrentParams(override_params)); { // Default scheduling options. MockThread thread; OLA_ASSERT_TRUE(RunThread(&thread)); OLA_ASSERT_EQ(default_params.policy, thread.GetSchedulingParams().policy); OLA_ASSERT_EQ(default_params.priority, thread.GetSchedulingParams().priority); } { // A thread that explicitly sets scheduling params. Thread::Options options; options.name = "ExplicitSchedParamsRR"; options.policy = SCHED_RR; options.priority = max_priority; MockThread thread(options); OLA_ASSERT_TRUE(RunThread(&thread)); OLA_ASSERT_EQ(static_cast<int>(SCHED_RR), thread.GetSchedulingParams().policy); OLA_ASSERT_EQ(max_priority, thread.GetSchedulingParams().priority); } { // A thread that inherits scheduling params. Thread::Options options; options.name = "InheritSchedParams"; options.inheritsched = PTHREAD_INHERIT_SCHED; MockThread thread(options); OLA_ASSERT_TRUE(RunThread(&thread)); OLA_ASSERT_EQ(override_params.policy, thread.GetSchedulingParams().policy); OLA_ASSERT_EQ(override_params.priority, thread.GetSchedulingParams().priority); } #else OLA_WARN << "Scheduling options are not supported on Windows.."; #endif // !_WIN32 }