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
#ifndef FOLLY_BENCHMARK_H_
#define FOLLY_BENCHMARK_H_
+#include "folly/Portability.h"
#include "folly/Preprocessor.h" // for FB_ANONYMOUS_VARIABLE
#include <cassert>
#include <ctime>
DECLARE_bool(benchmark);
-
namespace folly {
/**
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
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
#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 <time.h>
+#else
+#include "folly/detail/Clock.h"
+#endif
+
#endif // FOLLY_PORTABILITY_H_
[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 \
--- /dev/null
+/*
+ * 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 <errno.h>
+#include <mach/mach_time.h>
+
+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
--- /dev/null
+/*
+ * 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 <ctime>
+#include <cstdint>
+
+#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_ */
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)