diff options
author | Yabin Cui <yabinc@google.com> | 2015-05-08 12:01:52 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2015-05-08 13:12:01 -0700 |
commit | 5c0996a96970eb7cf93d3203313a2532c119f1a7 (patch) | |
tree | 215389354714a898ed7b90420d99f38f3e439348 /tests | |
parent | 3da136aa47e2d1608b98abb2580f024b36f92831 (diff) | |
download | bionic-5c0996a96970eb7cf93d3203313a2532c119f1a7.zip bionic-5c0996a96970eb7cf93d3203313a2532c119f1a7.tar.gz bionic-5c0996a96970eb7cf93d3203313a2532c119f1a7.tar.bz2 |
Fix timer flaky test in lollipop-mr1-cts-dev.
It is partically cherry-pick from https://android-review.googlesource.com/#/c/123410/.
And as lollipop-mr1-cts-dev still uses stlport, <stdatomic.h> is used instead of <atomic>.
Bug: 20677618
Change-Id: I952a6fd074facc4227c955fecf3ecbfbbaec4193
Diffstat (limited to 'tests')
-rw-r--r-- | tests/time_test.cpp | 149 |
1 files changed, 76 insertions, 73 deletions
diff --git a/tests/time_test.cpp b/tests/time_test.cpp index 9880d2c..97e371c 100644 --- a/tests/time_test.cpp +++ b/tests/time_test.cpp @@ -21,6 +21,7 @@ #include <gtest/gtest.h> #include <pthread.h> #include <signal.h> +#include <stdatomic.h> #include <sys/syscall.h> #include <sys/types.h> #include <sys/wait.h> @@ -171,7 +172,7 @@ TEST(time, timer_create) { ASSERT_EQ(0, timer_delete(timer_id)); } -static int timer_create_SIGEV_SIGNAL_signal_handler_invocation_count = 0; +static int timer_create_SIGEV_SIGNAL_signal_handler_invocation_count; static void timer_create_SIGEV_SIGNAL_signal_handler(int signal_number) { ++timer_create_SIGEV_SIGNAL_signal_handler_invocation_count; ASSERT_EQ(SIGUSR1, signal_number); @@ -186,6 +187,7 @@ TEST(time, timer_create_SIGEV_SIGNAL) { timer_t timer_id; ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id)); + timer_create_SIGEV_SIGNAL_signal_handler_invocation_count = 0; ScopedSignalHandler ssh(SIGUSR1, timer_create_SIGEV_SIGNAL_signal_handler); ASSERT_EQ(0, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count); @@ -202,12 +204,20 @@ TEST(time, timer_create_SIGEV_SIGNAL) { } struct Counter { - volatile int value; + private: + atomic_int value; timer_t timer_id; sigevent_t se; bool timer_valid; - Counter(void (*fn)(sigval_t)) : value(0), timer_valid(false) { + void Create() { + ASSERT_FALSE(timer_valid); + ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &timer_id)); + timer_valid = true; + } + + public: + Counter(void (*fn)(sigval_t)) : value(ATOMIC_VAR_INIT(0)), timer_valid(false) { memset(&se, 0, sizeof(se)); se.sigev_notify = SIGEV_THREAD; se.sigev_notify_function = fn; @@ -215,12 +225,6 @@ struct Counter { Create(); } - void Create() { - ASSERT_FALSE(timer_valid); - ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &timer_id)); - timer_valid = true; - } - void DeleteTimer() { ASSERT_TRUE(timer_valid); ASSERT_EQ(0, timer_delete(timer_id)); @@ -233,26 +237,30 @@ struct Counter { } } + int Value() { + return atomic_load(&value); + } + void SetTime(time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) { ::SetTime(timer_id, value_s, value_ns, interval_s, interval_ns); } bool ValueUpdated() { - volatile int current_value = value; + int current_value = atomic_load(&value); time_t start = time(NULL); - while (current_value == value && (time(NULL) - start) < 5) { + while (current_value == atomic_load(&value) && (time(NULL) - start) < 5) { } - return current_value != value; + return current_value != atomic_load(&value); } static void CountNotifyFunction(sigval_t value) { Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr); - ++cd->value; + atomic_fetch_add(&cd->value, 1); } static void CountAndDisarmNotifyFunction(sigval_t value) { Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr); - ++cd->value; + atomic_fetch_add(&cd->value, 1); // Setting the initial expiration time to 0 disarms the timer. cd->SetTime(0, 0, 1, 0); @@ -261,30 +269,29 @@ struct Counter { TEST(time, timer_settime_0) { Counter counter(Counter::CountAndDisarmNotifyFunction); - ASSERT_TRUE(counter.timer_valid); - - ASSERT_EQ(0, counter.value); + ASSERT_EQ(0, counter.Value()); counter.SetTime(0, 1, 1, 0); usleep(500000); // The count should just be 1 because we disarmed the timer the first time it fired. - ASSERT_EQ(1, counter.value); + ASSERT_EQ(1, counter.Value()); } TEST(time, timer_settime_repeats) { Counter counter(Counter::CountNotifyFunction); - ASSERT_TRUE(counter.timer_valid); - - ASSERT_EQ(0, counter.value); + ASSERT_EQ(0, counter.Value()); counter.SetTime(0, 1, 0, 10); ASSERT_TRUE(counter.ValueUpdated()); ASSERT_TRUE(counter.ValueUpdated()); ASSERT_TRUE(counter.ValueUpdated()); + counter.DeleteTimer(); + // Add a sleep as other threads may be calling the callback function when the timer is deleted. + usleep(500000); } -static int timer_create_NULL_signal_handler_invocation_count = 0; +static int timer_create_NULL_signal_handler_invocation_count; static void timer_create_NULL_signal_handler(int signal_number) { ++timer_create_NULL_signal_handler_invocation_count; ASSERT_EQ(SIGALRM, signal_number); @@ -295,6 +302,7 @@ TEST(time, timer_create_NULL) { timer_t timer_id; ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, NULL, &timer_id)); + timer_create_NULL_signal_handler_invocation_count = 0; ScopedSignalHandler ssh(SIGALRM, timer_create_NULL_signal_handler); ASSERT_EQ(0, timer_create_NULL_signal_handler_invocation_count); @@ -341,22 +349,59 @@ TEST(time, timer_delete_multiple) { TEST(time, timer_create_multiple) { Counter counter1(Counter::CountNotifyFunction); - ASSERT_TRUE(counter1.timer_valid); Counter counter2(Counter::CountNotifyFunction); - ASSERT_TRUE(counter2.timer_valid); Counter counter3(Counter::CountNotifyFunction); - ASSERT_TRUE(counter3.timer_valid); - ASSERT_EQ(0, counter1.value); - ASSERT_EQ(0, counter2.value); - ASSERT_EQ(0, counter3.value); + ASSERT_EQ(0, counter1.Value()); + ASSERT_EQ(0, counter2.Value()); + ASSERT_EQ(0, counter3.Value()); counter2.SetTime(0, 1, 0, 0); usleep(500000); - EXPECT_EQ(0, counter1.value); - EXPECT_EQ(1, counter2.value); - EXPECT_EQ(0, counter3.value); + EXPECT_EQ(0, counter1.Value()); + EXPECT_EQ(1, counter2.Value()); + EXPECT_EQ(0, counter3.Value()); +} + +// Test to verify that disarming a repeatable timer disables the callbacks. +TEST(time, timer_disarm_terminates) { + Counter counter(Counter::CountNotifyFunction); + ASSERT_EQ(0, counter.Value()); + + counter.SetTime(0, 1, 0, 1); + ASSERT_TRUE(counter.ValueUpdated()); + ASSERT_TRUE(counter.ValueUpdated()); + ASSERT_TRUE(counter.ValueUpdated()); + + counter.SetTime(0, 0, 0, 0); + // Add a sleep as the kernel may have pending events when the timer is disarmed. + usleep(500000); + int value = counter.Value(); + usleep(500000); + + // Verify the counter has not been incremented. + ASSERT_EQ(value, counter.Value()); +} + +// Test to verify that deleting a repeatable timer disables the callbacks. +TEST(time, timer_delete_terminates) { + Counter counter(Counter::CountNotifyFunction); + ASSERT_EQ(0, counter.Value()); + + counter.SetTime(0, 1, 0, 1); + ASSERT_TRUE(counter.ValueUpdated()); + ASSERT_TRUE(counter.ValueUpdated()); + ASSERT_TRUE(counter.ValueUpdated()); + + counter.DeleteTimer(); + // Add a sleep as other threads may be calling the callback function when the timer is deleted. + usleep(500000); + int value = counter.Value(); + usleep(500000); + + // Verify the counter has not been incremented. + ASSERT_EQ(value, counter.Value()); } struct TimerDeleteData { @@ -424,45 +469,3 @@ TEST(time, clock_gettime) { ASSERT_EQ(0, ts2.tv_sec); ASSERT_LT(ts2.tv_nsec, 1000000); } - -// Test to verify that disarming a repeatable timer disables the -// callbacks. -TEST(time, timer_disarm_terminates) { - Counter counter(Counter::CountNotifyFunction); - ASSERT_TRUE(counter.timer_valid); - - ASSERT_EQ(0, counter.value); - - counter.SetTime(0, 1, 0, 1); - ASSERT_TRUE(counter.ValueUpdated()); - ASSERT_TRUE(counter.ValueUpdated()); - ASSERT_TRUE(counter.ValueUpdated()); - - counter.SetTime(0, 0, 1, 0); - volatile int value = counter.value; - usleep(500000); - - // Verify the counter has not been incremented. - ASSERT_EQ(value, counter.value); -} - -// Test to verify that deleting a repeatable timer disables the -// callbacks. -TEST(time, timer_delete_terminates) { - Counter counter(Counter::CountNotifyFunction); - ASSERT_TRUE(counter.timer_valid); - - ASSERT_EQ(0, counter.value); - - counter.SetTime(0, 1, 0, 1); - ASSERT_TRUE(counter.ValueUpdated()); - ASSERT_TRUE(counter.ValueUpdated()); - ASSERT_TRUE(counter.ValueUpdated()); - - counter.DeleteTimer(); - volatile int value = counter.value; - usleep(500000); - - // Verify the counter has not been incremented. - ASSERT_EQ(value, counter.value); -} |