summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2015-05-08 12:01:52 -0700
committerYabin Cui <yabinc@google.com>2015-05-08 13:12:01 -0700
commit5c0996a96970eb7cf93d3203313a2532c119f1a7 (patch)
tree215389354714a898ed7b90420d99f38f3e439348 /tests
parent3da136aa47e2d1608b98abb2580f024b36f92831 (diff)
downloadbionic-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.cpp149
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);
-}