blob: a04c449761a5873ca592e1382dae737ad37d1eda [file] [log] [blame]
Elliott Hughese0175ca2013-03-14 14:38:08 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Elliott Hughes4b558f52014-03-04 15:58:02 -080017#include <time.h>
18
19#include <errno.h>
Elliott Hughese0175ca2013-03-14 14:38:08 -070020#include <gtest/gtest.h>
Elliott Hughes329103d2014-04-25 16:55:04 -070021#include <pthread.h>
Elliott Hughes4b558f52014-03-04 15:58:02 -080022#include <signal.h>
Elliott Hughes625993d2014-07-15 16:53:13 -070023#include <sys/syscall.h>
Brian Carlstrombe1d91d2014-03-08 15:05:26 -080024#include <sys/types.h>
25#include <sys/wait.h>
Yabin Cuid5c65272014-11-26 14:04:26 -080026#include <unistd.h>
Yabin Cui95f1ee22015-01-13 19:53:15 -080027#include <atomic>
Elliott Hughese0175ca2013-03-14 14:38:08 -070028
Elliott Hughes4b558f52014-03-04 15:58:02 -080029#include "ScopedSignalHandler.h"
Elliott Hughese0175ca2013-03-14 14:38:08 -070030
Elliott Hughes04303f52014-09-18 16:11:59 -070031#include "private/bionic_constants.h"
32
Elliott Hughesee178bf2013-07-12 11:25:20 -070033TEST(time, gmtime) {
34 time_t t = 0;
35 tm* broken_down = gmtime(&t);
36 ASSERT_TRUE(broken_down != NULL);
37 ASSERT_EQ(0, broken_down->tm_sec);
38 ASSERT_EQ(0, broken_down->tm_min);
39 ASSERT_EQ(0, broken_down->tm_hour);
40 ASSERT_EQ(1, broken_down->tm_mday);
41 ASSERT_EQ(0, broken_down->tm_mon);
42 ASSERT_EQ(1970, broken_down->tm_year + 1900);
43}
Elliott Hughes7843d442013-08-22 11:37:32 -070044
Elliott Hughes329103d2014-04-25 16:55:04 -070045static void* gmtime_no_stack_overflow_14313703_fn(void*) {
46 const char* original_tz = getenv("TZ");
47 // Ensure we'll actually have to enter tzload by using a time zone that doesn't exist.
48 setenv("TZ", "gmtime_stack_overflow_14313703", 1);
49 tzset();
50 if (original_tz != NULL) {
51 setenv("TZ", original_tz, 1);
52 }
53 tzset();
54 return NULL;
55}
56
57TEST(time, gmtime_no_stack_overflow_14313703) {
58 // Is it safe to call tzload on a thread with a small stack?
59 // http://b/14313703
60 // https://code.google.com/p/android/issues/detail?id=61130
61 pthread_attr_t attributes;
62 ASSERT_EQ(0, pthread_attr_init(&attributes));
63#if defined(__BIONIC__)
64 ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, PTHREAD_STACK_MIN));
65#else
66 // PTHREAD_STACK_MIN not currently in the host GCC sysroot.
67 ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 4 * getpagesize()));
68#endif
69
70 pthread_t t;
71 ASSERT_EQ(0, pthread_create(&t, &attributes, gmtime_no_stack_overflow_14313703_fn, NULL));
72 void* result;
73 ASSERT_EQ(0, pthread_join(t, &result));
74}
75
Satoru Takeuchi154e2022014-05-27 17:04:04 +090076TEST(time, mktime_empty_TZ) {
77 // tzcode used to have a bug where it didn't reinitialize some internal state.
78
79 // Choose a time where DST is set.
80 struct tm t;
81 memset(&t, 0, sizeof(tm));
82 t.tm_year = 1980 - 1900;
83 t.tm_mon = 6;
84 t.tm_mday = 2;
85
86 setenv("TZ", "America/Los_Angeles", 1);
87 tzset();
88 ASSERT_EQ(static_cast<time_t>(331372800U), mktime(&t));
89
90 memset(&t, 0, sizeof(tm));
91 t.tm_year = 1980 - 1900;
92 t.tm_mon = 6;
93 t.tm_mday = 2;
94
95 setenv("TZ", "", 1); // Implies UTC.
96 tzset();
97 ASSERT_EQ(static_cast<time_t>(331344000U), mktime(&t));
98}
99
Elliott Hughes7843d442013-08-22 11:37:32 -0700100TEST(time, mktime_10310929) {
101 struct tm t;
102 memset(&t, 0, sizeof(tm));
103 t.tm_year = 200;
104 t.tm_mon = 2;
105 t.tm_mday = 10;
106
Elliott Hughes0c401522013-10-18 16:21:54 -0700107#if !defined(__LP64__)
108 // 32-bit bionic stupidly had a signed 32-bit time_t.
Elliott Hughes7843d442013-08-22 11:37:32 -0700109 ASSERT_EQ(-1, mktime(&t));
Elliott Hughes0c401522013-10-18 16:21:54 -0700110#else
111 // Everyone else should be using a signed 64-bit time_t.
112 ASSERT_GE(sizeof(time_t) * 8, 64U);
113
114 setenv("TZ", "America/Los_Angeles", 1);
115 tzset();
116 ASSERT_EQ(static_cast<time_t>(4108348800U), mktime(&t));
Elliott Hughes0c401522013-10-18 16:21:54 -0700117
118 setenv("TZ", "UTC", 1);
119 tzset();
120 ASSERT_EQ(static_cast<time_t>(4108320000U), mktime(&t));
Elliott Hughes7843d442013-08-22 11:37:32 -0700121#endif
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800122}
Elliott Hughes4b558f52014-03-04 15:58:02 -0800123
Elliott Hughes3e3409a2014-03-10 18:19:03 -0700124TEST(time, strftime) {
125 setenv("TZ", "UTC", 1);
126
127 struct tm t;
128 memset(&t, 0, sizeof(tm));
129 t.tm_year = 200;
130 t.tm_mon = 2;
131 t.tm_mday = 10;
132
133 char buf[64];
134
135 // Seconds since the epoch.
136#if defined(__BIONIC__) || defined(__LP64__) // Not 32-bit glibc.
137 EXPECT_EQ(10U, strftime(buf, sizeof(buf), "%s", &t));
138 EXPECT_STREQ("4108320000", buf);
139#endif
140
141 // Date and time as text.
142 EXPECT_EQ(24U, strftime(buf, sizeof(buf), "%c", &t));
143 EXPECT_STREQ("Sun Mar 10 00:00:00 2100", buf);
144}
145
Elliott Hughesa9cac4c2015-11-12 16:51:31 -0800146TEST(time, strftime_null_tm_zone) {
147 // Netflix on Nexus Player wouldn't start (http://b/25170306).
148 struct tm t;
149 memset(&t, 0, sizeof(tm));
150
151 char buf[64];
152
153 setenv("TZ", "America/Los_Angeles", 1);
154 tzset();
155
156 t.tm_isdst = 0; // "0 if Daylight Savings Time is not in effect".
157 EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
158 EXPECT_STREQ("<PST>", buf);
159
160#if defined(__BIONIC__) // glibc 2.19 only copes with tm_isdst being 0 and 1.
161 t.tm_isdst = 2; // "positive if Daylight Savings Time is in effect"
162 EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
163 EXPECT_STREQ("<PDT>", buf);
164
165 t.tm_isdst = -123; // "and negative if the information is not available".
166 EXPECT_EQ(2U, strftime(buf, sizeof(buf), "<%Z>", &t));
167 EXPECT_STREQ("<>", buf);
168#endif
169
170 setenv("TZ", "UTC", 1);
171 tzset();
172
173 t.tm_isdst = 0;
174 EXPECT_EQ(5U, strftime(buf, sizeof(buf), "<%Z>", &t));
175 EXPECT_STREQ("<UTC>", buf);
176
177#if defined(__BIONIC__) // glibc 2.19 thinks UTC DST is "UTC".
178 t.tm_isdst = 1; // UTC has no DST.
179 EXPECT_EQ(2U, strftime(buf, sizeof(buf), "<%Z>", &t));
180 EXPECT_STREQ("<>", buf);
181#endif
182}
183
Elliott Hughes3e3409a2014-03-10 18:19:03 -0700184TEST(time, strptime) {
185 setenv("TZ", "UTC", 1);
186
187 struct tm t;
188 char buf[64];
189
190 memset(&t, 0, sizeof(t));
191 strptime("11:14", "%R", &t);
192 strftime(buf, sizeof(buf), "%H:%M", &t);
193 EXPECT_STREQ("11:14", buf);
194
195 memset(&t, 0, sizeof(t));
196 strptime("09:41:53", "%T", &t);
197 strftime(buf, sizeof(buf), "%H:%M:%S", &t);
198 EXPECT_STREQ("09:41:53", buf);
199}
200
Elliott Hughes4b558f52014-03-04 15:58:02 -0800201void SetTime(timer_t t, time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
202 itimerspec ts;
203 ts.it_value.tv_sec = value_s;
204 ts.it_value.tv_nsec = value_ns;
205 ts.it_interval.tv_sec = interval_s;
206 ts.it_interval.tv_nsec = interval_ns;
Yabin Cuid1ade7c2015-06-18 17:01:11 -0700207 ASSERT_EQ(0, timer_settime(t, 0, &ts, NULL));
Elliott Hughes4b558f52014-03-04 15:58:02 -0800208}
209
210static void NoOpNotifyFunction(sigval_t) {
211}
212
213TEST(time, timer_create) {
214 sigevent_t se;
215 memset(&se, 0, sizeof(se));
216 se.sigev_notify = SIGEV_THREAD;
217 se.sigev_notify_function = NoOpNotifyFunction;
218 timer_t timer_id;
219 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
220
221 int pid = fork();
222 ASSERT_NE(-1, pid) << strerror(errno);
223
224 if (pid == 0) {
225 // Timers are not inherited by the child.
226 ASSERT_EQ(-1, timer_delete(timer_id));
227 ASSERT_EQ(EINVAL, errno);
228 _exit(0);
229 }
230
231 int status;
232 ASSERT_EQ(pid, waitpid(pid, &status, 0));
233 ASSERT_TRUE(WIFEXITED(status));
234 ASSERT_EQ(0, WEXITSTATUS(status));
235
236 ASSERT_EQ(0, timer_delete(timer_id));
237}
238
Yabin Cui95f1ee22015-01-13 19:53:15 -0800239static int timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800240static void timer_create_SIGEV_SIGNAL_signal_handler(int signal_number) {
241 ++timer_create_SIGEV_SIGNAL_signal_handler_invocation_count;
242 ASSERT_EQ(SIGUSR1, signal_number);
243}
244
245TEST(time, timer_create_SIGEV_SIGNAL) {
246 sigevent_t se;
247 memset(&se, 0, sizeof(se));
248 se.sigev_notify = SIGEV_SIGNAL;
249 se.sigev_signo = SIGUSR1;
250
251 timer_t timer_id;
252 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
253
Yabin Cui95f1ee22015-01-13 19:53:15 -0800254 timer_create_SIGEV_SIGNAL_signal_handler_invocation_count = 0;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800255 ScopedSignalHandler ssh(SIGUSR1, timer_create_SIGEV_SIGNAL_signal_handler);
256
257 ASSERT_EQ(0, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
258
259 itimerspec ts;
260 ts.it_value.tv_sec = 0;
261 ts.it_value.tv_nsec = 1;
262 ts.it_interval.tv_sec = 0;
263 ts.it_interval.tv_nsec = 0;
Yabin Cuid1ade7c2015-06-18 17:01:11 -0700264 ASSERT_EQ(0, timer_settime(timer_id, 0, &ts, NULL));
Elliott Hughes4b558f52014-03-04 15:58:02 -0800265
266 usleep(500000);
267 ASSERT_EQ(1, timer_create_SIGEV_SIGNAL_signal_handler_invocation_count);
268}
269
270struct Counter {
Yabin Cui95f1ee22015-01-13 19:53:15 -0800271 private:
272 std::atomic<int> value;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800273 timer_t timer_id;
274 sigevent_t se;
Christopher Ferris62d84b12014-10-20 19:09:19 -0700275 bool timer_valid;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800276
Elliott Hughes4b558f52014-03-04 15:58:02 -0800277 void Create() {
Christopher Ferris62d84b12014-10-20 19:09:19 -0700278 ASSERT_FALSE(timer_valid);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800279 ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &timer_id));
Christopher Ferris62d84b12014-10-20 19:09:19 -0700280 timer_valid = true;
281 }
282
Yabin Cui95f1ee22015-01-13 19:53:15 -0800283 public:
284 Counter(void (*fn)(sigval_t)) : value(0), timer_valid(false) {
285 memset(&se, 0, sizeof(se));
286 se.sigev_notify = SIGEV_THREAD;
287 se.sigev_notify_function = fn;
288 se.sigev_value.sival_ptr = this;
289 Create();
290 }
Christopher Ferris62d84b12014-10-20 19:09:19 -0700291 void DeleteTimer() {
292 ASSERT_TRUE(timer_valid);
293 ASSERT_EQ(0, timer_delete(timer_id));
294 timer_valid = false;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800295 }
296
297 ~Counter() {
Christopher Ferris62d84b12014-10-20 19:09:19 -0700298 if (timer_valid) {
299 DeleteTimer();
Elliott Hughes4b558f52014-03-04 15:58:02 -0800300 }
301 }
302
Yabin Cui95f1ee22015-01-13 19:53:15 -0800303 int Value() const {
304 return value;
305 }
306
Christopher Ferris62d84b12014-10-20 19:09:19 -0700307 void SetTime(time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
308 ::SetTime(timer_id, value_s, value_ns, interval_s, interval_ns);
309 }
310
311 bool ValueUpdated() {
Yabin Cui95f1ee22015-01-13 19:53:15 -0800312 int current_value = value;
Christopher Ferris62d84b12014-10-20 19:09:19 -0700313 time_t start = time(NULL);
314 while (current_value == value && (time(NULL) - start) < 5) {
315 }
316 return current_value != value;
317 }
318
Elliott Hughes4b558f52014-03-04 15:58:02 -0800319 static void CountNotifyFunction(sigval_t value) {
320 Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
321 ++cd->value;
322 }
323
324 static void CountAndDisarmNotifyFunction(sigval_t value) {
325 Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
326 ++cd->value;
327
328 // Setting the initial expiration time to 0 disarms the timer.
Christopher Ferris62d84b12014-10-20 19:09:19 -0700329 cd->SetTime(0, 0, 1, 0);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800330 }
331};
332
333TEST(time, timer_settime_0) {
334 Counter counter(Counter::CountAndDisarmNotifyFunction);
Yabin Cui95f1ee22015-01-13 19:53:15 -0800335 ASSERT_EQ(0, counter.Value());
Elliott Hughes4b558f52014-03-04 15:58:02 -0800336
Yabin Cuibf572d92015-08-11 11:23:16 -0700337 counter.SetTime(0, 500000000, 1, 0);
338 sleep(1);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800339
340 // The count should just be 1 because we disarmed the timer the first time it fired.
Yabin Cui95f1ee22015-01-13 19:53:15 -0800341 ASSERT_EQ(1, counter.Value());
Elliott Hughes4b558f52014-03-04 15:58:02 -0800342}
343
344TEST(time, timer_settime_repeats) {
345 Counter counter(Counter::CountNotifyFunction);
Yabin Cui95f1ee22015-01-13 19:53:15 -0800346 ASSERT_EQ(0, counter.Value());
Elliott Hughes4b558f52014-03-04 15:58:02 -0800347
Christopher Ferris62d84b12014-10-20 19:09:19 -0700348 counter.SetTime(0, 1, 0, 10);
349 ASSERT_TRUE(counter.ValueUpdated());
350 ASSERT_TRUE(counter.ValueUpdated());
351 ASSERT_TRUE(counter.ValueUpdated());
Yabin Cui95f1ee22015-01-13 19:53:15 -0800352 counter.DeleteTimer();
353 // Add a sleep as other threads may be calling the callback function when the timer is deleted.
354 usleep(500000);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800355}
356
Yabin Cui95f1ee22015-01-13 19:53:15 -0800357static int timer_create_NULL_signal_handler_invocation_count;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800358static void timer_create_NULL_signal_handler(int signal_number) {
359 ++timer_create_NULL_signal_handler_invocation_count;
360 ASSERT_EQ(SIGALRM, signal_number);
361}
362
363TEST(time, timer_create_NULL) {
364 // A NULL sigevent* is equivalent to asking for SIGEV_SIGNAL for SIGALRM.
365 timer_t timer_id;
366 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, NULL, &timer_id));
367
Yabin Cui95f1ee22015-01-13 19:53:15 -0800368 timer_create_NULL_signal_handler_invocation_count = 0;
Elliott Hughes4b558f52014-03-04 15:58:02 -0800369 ScopedSignalHandler ssh(SIGALRM, timer_create_NULL_signal_handler);
370
371 ASSERT_EQ(0, timer_create_NULL_signal_handler_invocation_count);
372
373 SetTime(timer_id, 0, 1, 0, 0);
374 usleep(500000);
375
376 ASSERT_EQ(1, timer_create_NULL_signal_handler_invocation_count);
377}
378
379TEST(time, timer_create_EINVAL) {
380 clockid_t invalid_clock = 16;
381
382 // A SIGEV_SIGNAL timer is easy; the kernel does all that.
383 timer_t timer_id;
384 ASSERT_EQ(-1, timer_create(invalid_clock, NULL, &timer_id));
385 ASSERT_EQ(EINVAL, errno);
386
387 // A SIGEV_THREAD timer is more interesting because we have stuff to clean up.
388 sigevent_t se;
389 memset(&se, 0, sizeof(se));
390 se.sigev_notify = SIGEV_THREAD;
391 se.sigev_notify_function = NoOpNotifyFunction;
392 ASSERT_EQ(-1, timer_create(invalid_clock, &se, &timer_id));
393 ASSERT_EQ(EINVAL, errno);
394}
395
396TEST(time, timer_delete_multiple) {
397 timer_t timer_id;
398 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, NULL, &timer_id));
399 ASSERT_EQ(0, timer_delete(timer_id));
400 ASSERT_EQ(-1, timer_delete(timer_id));
401 ASSERT_EQ(EINVAL, errno);
402
403 sigevent_t se;
404 memset(&se, 0, sizeof(se));
405 se.sigev_notify = SIGEV_THREAD;
406 se.sigev_notify_function = NoOpNotifyFunction;
407 ASSERT_EQ(0, timer_create(CLOCK_MONOTONIC, &se, &timer_id));
408 ASSERT_EQ(0, timer_delete(timer_id));
409 ASSERT_EQ(-1, timer_delete(timer_id));
410 ASSERT_EQ(EINVAL, errno);
411}
412
413TEST(time, timer_create_multiple) {
414 Counter counter1(Counter::CountNotifyFunction);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800415 Counter counter2(Counter::CountNotifyFunction);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800416 Counter counter3(Counter::CountNotifyFunction);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800417
Yabin Cui95f1ee22015-01-13 19:53:15 -0800418 ASSERT_EQ(0, counter1.Value());
419 ASSERT_EQ(0, counter2.Value());
420 ASSERT_EQ(0, counter3.Value());
Elliott Hughes4b558f52014-03-04 15:58:02 -0800421
Yabin Cui410c1ad2015-06-18 16:19:02 -0700422 counter2.SetTime(0, 500000000, 0, 0);
423 sleep(1);
Elliott Hughes4b558f52014-03-04 15:58:02 -0800424
Yabin Cui95f1ee22015-01-13 19:53:15 -0800425 EXPECT_EQ(0, counter1.Value());
426 EXPECT_EQ(1, counter2.Value());
427 EXPECT_EQ(0, counter3.Value());
428}
429
430// Test to verify that disarming a repeatable timer disables the callbacks.
431TEST(time, timer_disarm_terminates) {
432 Counter counter(Counter::CountNotifyFunction);
433 ASSERT_EQ(0, counter.Value());
434
435 counter.SetTime(0, 1, 0, 1);
436 ASSERT_TRUE(counter.ValueUpdated());
437 ASSERT_TRUE(counter.ValueUpdated());
438 ASSERT_TRUE(counter.ValueUpdated());
439
440 counter.SetTime(0, 0, 0, 0);
441 // Add a sleep as the kernel may have pending events when the timer is disarmed.
442 usleep(500000);
443 int value = counter.Value();
444 usleep(500000);
445
446 // Verify the counter has not been incremented.
447 ASSERT_EQ(value, counter.Value());
448}
449
450// Test to verify that deleting a repeatable timer disables the callbacks.
451TEST(time, timer_delete_terminates) {
452 Counter counter(Counter::CountNotifyFunction);
453 ASSERT_EQ(0, counter.Value());
454
455 counter.SetTime(0, 1, 0, 1);
456 ASSERT_TRUE(counter.ValueUpdated());
457 ASSERT_TRUE(counter.ValueUpdated());
458 ASSERT_TRUE(counter.ValueUpdated());
459
460 counter.DeleteTimer();
461 // Add a sleep as other threads may be calling the callback function when the timer is deleted.
462 usleep(500000);
463 int value = counter.Value();
464 usleep(500000);
465
466 // Verify the counter has not been incremented.
467 ASSERT_EQ(value, counter.Value());
Elliott Hughes4b558f52014-03-04 15:58:02 -0800468}
Christopher Ferris753ad772014-03-20 20:47:45 -0700469
470struct TimerDeleteData {
471 timer_t timer_id;
472 pthread_t thread_id;
473 volatile bool complete;
474};
475
476static void TimerDeleteCallback(sigval_t value) {
477 TimerDeleteData* tdd = reinterpret_cast<TimerDeleteData*>(value.sival_ptr);
478
479 tdd->thread_id = pthread_self();
480 timer_delete(tdd->timer_id);
481 tdd->complete = true;
482}
483
484TEST(time, timer_delete_from_timer_thread) {
485 TimerDeleteData tdd;
486 sigevent_t se;
487
488 memset(&se, 0, sizeof(se));
489 se.sigev_notify = SIGEV_THREAD;
490 se.sigev_notify_function = TimerDeleteCallback;
491 se.sigev_value.sival_ptr = &tdd;
492
493 tdd.complete = false;
494 ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &tdd.timer_id));
495
496 itimerspec ts;
Christopher Ferris3da136a2015-02-18 17:11:47 -0800497 ts.it_value.tv_sec = 1;
498 ts.it_value.tv_nsec = 0;
Christopher Ferris753ad772014-03-20 20:47:45 -0700499 ts.it_interval.tv_sec = 0;
500 ts.it_interval.tv_nsec = 0;
Christopher Ferris3da136a2015-02-18 17:11:47 -0800501 ASSERT_EQ(0, timer_settime(tdd.timer_id, 0, &ts, NULL));
Christopher Ferris753ad772014-03-20 20:47:45 -0700502
503 time_t cur_time = time(NULL);
504 while (!tdd.complete && (time(NULL) - cur_time) < 5);
505 ASSERT_TRUE(tdd.complete);
506
507#if defined(__BIONIC__)
508 // Since bionic timers are implemented by creating a thread to handle the
509 // callback, verify that the thread actually completes.
510 cur_time = time(NULL);
511 while (pthread_detach(tdd.thread_id) != ESRCH && (time(NULL) - cur_time) < 5);
512 ASSERT_EQ(ESRCH, pthread_detach(tdd.thread_id));
513#endif
514}
Elliott Hughes625993d2014-07-15 16:53:13 -0700515
516TEST(time, clock_gettime) {
517 // Try to ensure that our vdso clock_gettime is working.
518 timespec ts1;
519 ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts1));
520 timespec ts2;
521 ASSERT_EQ(0, syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts2));
522
523 // What's the difference between the two?
524 ts2.tv_sec -= ts1.tv_sec;
525 ts2.tv_nsec -= ts1.tv_nsec;
526 if (ts2.tv_nsec < 0) {
527 --ts2.tv_sec;
Elliott Hughes04303f52014-09-18 16:11:59 -0700528 ts2.tv_nsec += NS_PER_S;
Elliott Hughes625993d2014-07-15 16:53:13 -0700529 }
530
531 // Should be less than (a very generous, to try to avoid flakiness) 1000000ns.
532 ASSERT_EQ(0, ts2.tv_sec);
533 ASSERT_LT(ts2.tv_nsec, 1000000);
534}
Alex Van Brunt8d0b2db2014-09-26 13:32:47 -0700535
536TEST(time, clock) {
Haruki Hasegawa18160252014-10-13 00:50:47 +0900537 // clock(3) is hard to test, but a 1s sleep should cost less than 1ms.
538 clock_t t0 = clock();
539 sleep(1);
540 clock_t t1 = clock();
541 ASSERT_LT(t1 - t0, CLOCKS_PER_SEC / 1000);
542}
543
Yabin Cuid5c65272014-11-26 14:04:26 -0800544pid_t GetInvalidPid() {
545 FILE* fp = fopen("/proc/sys/kernel/pid_max", "r");
546 long pid_max;
547 fscanf(fp, "%ld", &pid_max);
548 pid_t invalid_pid = static_cast<pid_t>(pid_max + 1);
549 fclose(fp);
550 return invalid_pid;
551}
552
553TEST(time, clock_getcpuclockid) {
554 // For current process.
555 clockid_t clockid;
556 ASSERT_EQ(0, clock_getcpuclockid(getpid(), &clockid));
557
558 timespec ts;
559 ASSERT_EQ(0, clock_gettime(clockid, &ts));
560
561 // For parent process.
562 ASSERT_EQ(0, clock_getcpuclockid(getppid(), &clockid));
563 ASSERT_EQ(0, clock_gettime(clockid, &ts));
564
565 // For invalid process.
566 // We can't use -1 for invalid pid here, because clock_getcpuclockid() can't detect it.
567 errno = 0;
568 ASSERT_EQ(ESRCH, clock_getcpuclockid(GetInvalidPid(), &clockid));
569 ASSERT_EQ(0, errno);
570}
571
Haruki Hasegawa18160252014-10-13 00:50:47 +0900572TEST(time, clock_settime) {
573 errno = 0;
574 timespec ts;
575 ASSERT_EQ(-1, clock_settime(-1, &ts));
576 ASSERT_EQ(EINVAL, errno);
577}
578
579TEST(time, clock_nanosleep) {
580 timespec in;
581 timespec out;
582 ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
Alex Van Brunt8d0b2db2014-09-26 13:32:47 -0700583}