From 725756045e03ea6f7ef00d02e883ef2914d06dde Mon Sep 17 00:00:00 2001
From: Yabin Cui <yabinc@google.com>
Date: Mon, 8 Dec 2014 11:54:12 -0800
Subject: [PATCH] Change _POSIX_CPUTIME macro to make it compitable with glibc.

Change-Id: I7a8dbb74bd622693c9fef60bd779687207517b7d
---
 libc/bionic/sysconf.cpp             | 12 ++++++++++--
 libc/include/machine/posix_limits.h |  4 ++--
 tests/unistd_test.cpp               |  4 ++--
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 418072107..411c23ab0 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -46,6 +46,10 @@ static int __sysconf_monotonic_clock() {
   return (rc == -1) ? -1 : _POSIX_VERSION;
 }
 
+static bool __sysconf_has_clock(clockid_t clock_id) {
+  return clock_getres(clock_id, NULL) == 0;
+}
+
 long sysconf(int name) {
   switch (name) {
     case _SC_ARG_MAX:           return ARG_MAX;
@@ -144,7 +148,9 @@ long sysconf(int name) {
     case _SC_ADVISORY_INFO:     return _POSIX_ADVISORY_INFO;
     case _SC_BARRIERS:          return _POSIX_BARRIERS;
     case _SC_CLOCK_SELECTION:   return _POSIX_CLOCK_SELECTION;
-    case _SC_CPUTIME:           return _POSIX_CPUTIME;
+    case _SC_CPUTIME:
+      return __sysconf_has_clock(CLOCK_PROCESS_CPUTIME_ID) ?_POSIX_VERSION : -1;
+
     case _SC_HOST_NAME_MAX:     return _POSIX_HOST_NAME_MAX;    // Minimum requirement.
     case _SC_IPV6:              return _POSIX_IPV6;
     case _SC_RAW_SOCKETS:       return _POSIX_RAW_SOCKETS;
@@ -156,7 +162,9 @@ long sysconf(int name) {
     case _SC_SPORADIC_SERVER:   return _POSIX_SPORADIC_SERVER;
     case _SC_SS_REPL_MAX:       return -1;
     case _SC_SYMLOOP_MAX:       return _POSIX_SYMLOOP_MAX;      // Minimum requirement.
-    case _SC_THREAD_CPUTIME:    return _POSIX_THREAD_CPUTIME;
+    case _SC_THREAD_CPUTIME:
+      return __sysconf_has_clock(CLOCK_THREAD_CPUTIME_ID) ? _POSIX_VERSION : -1;
+
     case _SC_THREAD_PROCESS_SHARED: return _POSIX_THREAD_PROCESS_SHARED;
     case _SC_THREAD_ROBUST_PRIO_INHERIT:  return _POSIX_THREAD_ROBUST_PRIO_INHERIT;
     case _SC_THREAD_ROBUST_PRIO_PROTECT:  return _POSIX_THREAD_ROBUST_PRIO_PROTECT;
diff --git a/libc/include/machine/posix_limits.h b/libc/include/machine/posix_limits.h
index 25887bef6..4ffe421f6 100644
--- a/libc/include/machine/posix_limits.h
+++ b/libc/include/machine/posix_limits.h
@@ -41,7 +41,7 @@
 #define _POSIX_CHILD_MAX            25
 #define _POSIX_CHOWN_RESTRICTED     1  /* yes, chown requires appropriate privileges */
 #define _POSIX_CLOCK_SELECTION      200809L
-#define _POSIX_CPUTIME              200809L
+#define _POSIX_CPUTIME              0  /* Use sysconf to detect support at runtime. */
 #define _POSIX_DELAYTIMER_MAX       32
 #define _POSIX_FSYNC                200809L  /* fdatasync() supported */
 #define _POSIX_HOST_NAME_MAX        255
@@ -90,7 +90,7 @@
 #define _POSIX_THREADS              200809L  /* we support threads */
 #define _POSIX_THREAD_ATTR_STACKADDR  200809L
 #define _POSIX_THREAD_ATTR_STACKSIZE  200809L
-#define _POSIX_THREAD_CPUTIME       200809L
+#define _POSIX_THREAD_CPUTIME       0  /* Use sysconf to detect support at runtime. */
 #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
 #define _POSIX_THREAD_KEYS_MAX      128
 #define _POSIX_THREAD_PRIORITY_SCHEDULING 200809L
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index b37687f18..fd27682db 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -530,7 +530,7 @@ TEST(unistd, _POSIX_macros_smoke) {
   EXPECT_GT(_POSIX_CHILD_MAX, 0);
   EXPECT_NE(_POSIX_CHOWN_RESTRICTED, -1);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_CLOCK_SELECTION);
-  EXPECT_EQ(_POSIX_VERSION, _POSIX_CPUTIME);
+  EXPECT_EQ(0, _POSIX_CPUTIME);             // Use sysconf to detect support at runtime.
   EXPECT_GT(_POSIX_DELAYTIMER_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_FSYNC);
   EXPECT_GT(_POSIX_HOST_NAME_MAX, 0);
@@ -573,7 +573,7 @@ TEST(unistd, _POSIX_macros_smoke) {
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREADS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKADDR);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKSIZE);
-  EXPECT_TRUE(_POSIX_VERSION ==  _POSIX_THREAD_CPUTIME || 0 == _POSIX_THREAD_CPUTIME);
+  EXPECT_EQ(0, _POSIX_THREAD_CPUTIME);       // Use sysconf to detect support at runtime.
   EXPECT_GT(_POSIX_THREAD_DESTRUCTOR_ITERATIONS, 0);
   EXPECT_GT(_POSIX_THREAD_KEYS_MAX, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIORITY_SCHEDULING);