bionic: tzset running hot
logd makes a non-insignificant number of calls to localtime, 3% of
the time in logd is spent performing __system_property_get within the
context of tzset_locked().
Bug: 23685592
Change-Id: I75f8c2d436b60374e92c166b87393abda9487af7
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index bf09c5e..3a8a367 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -1211,7 +1211,9 @@
settzname();
}
-#include <sys/system_properties.h> // For __system_property_get.
+#include <stdbool.h>
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h> // For __system_property_serial.
static void
tzset_locked(void)
@@ -1221,9 +1223,27 @@
name = getenv("TZ");
// try the "persist.sys.timezone" system property first
- static char buf[PROP_VALUE_MAX];
- if (name == NULL && __system_property_get("persist.sys.timezone", buf) > 0) {
- name = buf;
+ if (name == NULL) {
+ static const prop_info *pi;
+
+ if (!pi) {
+ pi = __system_property_find("persist.sys.timezone");
+ }
+ if (pi) {
+ static char buf[PROP_VALUE_MAX];
+ static uint32_t s = -1;
+ static bool ok = false;
+ uint32_t serial;
+
+ serial = __system_property_serial(pi);
+ if (serial != s) {
+ ok = __system_property_read(pi, 0, buf) > 0;
+ s = serial;
+ }
+ if (ok) {
+ name = buf;
+ }
+ }
}
if (name == NULL) {