From: Peter Griess Date: Mon, 23 Sep 2013 21:22:58 +0000 (-0500) Subject: Use Mach built-ins in lieu of clock_gettime(3) and friends. X-Git-Tag: v0.22.0~827 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=1342be122f3d7bdaa33880851786716b810591b8;p=folly.git Use Mach built-ins in lieu of clock_gettime(3) and friends. Summary: - Mach doesn't support clock_getres(3) or clock_gettime(3). Provide our own implementations by wrapping mach_timebase_info() and mach_absolute_time(). - Detect availability of of -lrt at configure time and don't link with it if it's not available. On Linux, this is what provides clock_gettime(3) and friends. Test Plan: - fbconfig -r folly && fbmake runtests - ./configure && make check on Ubuntu/FC/Mac Reviewed By: meyering@fb.com FB internal diff: D999131 --- diff --git a/folly/Benchmark.h b/folly/Benchmark.h index 5e155f28..7d35bcd7 100644 --- a/folly/Benchmark.h +++ b/folly/Benchmark.h @@ -17,6 +17,7 @@ #ifndef FOLLY_BENCHMARK_H_ #define FOLLY_BENCHMARK_H_ +#include "folly/Portability.h" #include "folly/Preprocessor.h" // for FB_ANONYMOUS_VARIABLE #include #include @@ -28,7 +29,6 @@ DECLARE_bool(benchmark); - namespace folly { /** diff --git a/folly/Makefile.am b/folly/Makefile.am index 195ceb9e..6b2965ce 100644 --- a/folly/Makefile.am +++ b/folly/Makefile.am @@ -112,6 +112,11 @@ libfolly_la_SOURCES = \ SpookyHashV1.cpp \ SpookyHashV2.cpp +if !HAVE_LINUX +nobase_follyinclude_HEADERS += detail/Clock.h +libfolly_la_SOURCES += detail/Clock.cpp +endif + FingerprintTables.cpp: generate_fingerprint_tables ./generate_fingerprint_tables @@ -120,7 +125,7 @@ libfollyfingerprint_la_SOURCES = \ libfollyfingerprint_la_LIBADD = libfolly.la libfollybenchmark_la_SOURCES = Benchmark.cpp -libfollybenchmark_la_LIBADD = -lrt libfolly.la +libfollybenchmark_la_LIBADD = libfolly.la libfollytimeout_queue_la_SOURCES = TimeoutQueue.cpp libfollytimeout_queue_la_LIBADD = libfolly.la diff --git a/folly/Portability.h b/folly/Portability.h index 9b77b5f5..608c1d9b 100644 --- a/folly/Portability.h +++ b/folly/Portability.h @@ -129,4 +129,12 @@ struct MaxAlign { char c; } __attribute__((aligned)); #define FOLLY_NAMESPACE_STD_END } #endif +// Some platforms lack clock_gettime(2) and clock_getres(2). Inject our own +// versions of these into the global namespace. +#if FOLLY_HAVE_CLOCK_GETTIME +#include +#else +#include "folly/detail/Clock.h" +#endif + #endif // FOLLY_PORTABILITY_H_ diff --git a/folly/configure.ac b/folly/configure.ac index 6d9fb1e5..2dc854aa 100644 --- a/folly/configure.ac +++ b/folly/configure.ac @@ -79,6 +79,15 @@ AC_COMPILE_IFELSE( [Define to "override" if the compiler supports C++11 "override"])] ) +# Check for clock_gettime(2). This is not in an AC_CHECK_FUNCS() because we +# want to link with librt if necessary. +AC_SEARCH_LIBS([clock_gettime], [rt], + AC_DEFINE( + [HAVE_CLOCK_GETTIME], + [1], + [Define to 1 if we support clock_gettime(2).]), + []) + # Checks for library functions. AC_CHECK_FUNCS([getdelim \ gettimeofday \ diff --git a/folly/detail/Clock.cpp b/folly/detail/Clock.cpp new file mode 100644 index 00000000..d6c4b12a --- /dev/null +++ b/folly/detail/Clock.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2013 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "folly/detail/Clock.h" + +#if __MACH__ +#include +#include + +static mach_timebase_info_data_t tb_info; +static bool tb_init = mach_timebase_info(&tb_info) == KERN_SUCCESS; + +int clock_gettime(clockid_t clk_id, struct timespec* ts) { + if (!tb_init) { + errno = EINVAL; + return -1; + } + + uint64_t now_ticks = mach_absolute_time(); + uint64_t now_ns = (now_ticks * tb_info.numer) / tb_info.denom; + ts->tv_sec = now_ns / 1000000000; + ts->tv_nsec = now_ns % 1000000000; + + return 0; +} + +int clock_getres(clockid_t clk_id, struct timespec* ts) { + if (!tb_init) { + errno = EINVAL; + return -1; + } + + ts->tv_sec = 0; + ts->tv_nsec = tb_info.numer / tb_info.denom; + + return 0; +} +#else +#error No clock_gettime(2) compatibility wrapper available for this platform. +#endif diff --git a/folly/detail/Clock.h b/folly/detail/Clock.h new file mode 100644 index 00000000..8f6e6a4f --- /dev/null +++ b/folly/detail/Clock.h @@ -0,0 +1,36 @@ +/* + * Copyright 2013 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOLLY_DETAIL_CLOCK_H_ +#define FOLLY_DETAIL_CLOCK_H_ + +#include +#include + +#include "folly/folly-config.h" + +#if FOLLY_HAVE_CLOCK_GETTIME +#error This should only be used as a workaround for platforms \ + that do not support clock_gettime(2). +#endif + +typedef uint8_t clockid_t; +#define CLOCK_REALTIME 0 + +int clock_gettime(clockid_t clk_id, struct timespec* ts); +int clock_getres(clockid_t clk_id, struct timespec* ts); + +#endif /* FOLLY_DETAIL_CLOCK_H_ */ diff --git a/folly/test/Makefile.am b/folly/test/Makefile.am index 3680960e..57494e32 100644 --- a/folly/test/Makefile.am +++ b/folly/test/Makefile.am @@ -177,11 +177,11 @@ cpuid_test_LDADD = libgtestmain.la $(top_builddir)/libfolly.la TESTS += cpuid_test spooky_hash_v1_test_SOURCES = SpookyHashV1Test.cpp -spooky_hash_v1_test_LDADD = -lrt $(top_builddir)/libfolly.la $(top_builddir)/libfollybenchmark.la +spooky_hash_v1_test_LDADD = $(top_builddir)/libfolly.la $(top_builddir)/libfollybenchmark.la TESTS += spooky_hash_v1_test spooky_hash_v2_test_SOURCES = SpookyHashV2Test.cpp -spooky_hash_v2_test_LDADD = -lrt $(top_builddir)/libfolly.la $(top_builddir)/libfollybenchmark.la +spooky_hash_v2_test_LDADD = $(top_builddir)/libfolly.la $(top_builddir)/libfollybenchmark.la TESTS += spooky_hash_v2_test check_PROGRAMS= $(TESTS)